对象无法通过反序列化,因为"集合具有固定大小".

Rud*_*dis 5 c# serialization json json.net

我有一个简单的实例代码示例.我需要序列化为JSON并反序列化类的后退对象,TestClass派生自Letters.这两个类都有带参数的构造函数.

    public class TestClass : Letters
    {
        public string[] Names { get; private set; }

        public TestClass(string[] names)
            : base(names)
           // : base(new [] { "A", "B", })
           // : base(names.Select(a => a.Substring(0, 1)).ToArray())
        {
            Names = names;
        }
    }

    public abstract class Letters
    {
        public string[] FirstLetters { get; private set; }

        protected Letters(string[] letters)
        {
            FirstLetters = letters;
        }
    }
Run Code Online (Sandbox Code Playgroud)

对象TestClass被序列化为有效的JSON,但是当我尝试将其反序列化回到对象时,NotSupportedException抛出,消息Collection具有固定大小.

这是我的测试

    [Fact]
    public void JsonNamesTest()
    {
        var expected = new TestClass(new [] { "Alex", "Peter", "John", });

        var serialized = JsonConvert.SerializeObject(expected);
        Console.WriteLine(serialized);

        Assert.False(string.IsNullOrWhiteSpace(serialized));

        var actual = JsonConvert.DeserializeObject<TestClass>(serialized);

        AssertEx.PrimitivePropertiesEqual(expected, actual);
    }
Run Code Online (Sandbox Code Playgroud)

Bri*_*ers 6

Json.Net需要所有类都有一个无参数构造函数来反序列化它们,否则它不知道如何调用构造函数.在不更改类的情况下解决此问题的一种方法是JsonConverter创建一个将从JSON创建对象实例的自定义.例如:

class TestClassConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(TestClass) == objectType;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        string[] names = jo["Names"].ToObject<string[]>();
        return new TestClass(names);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,像这样反序列化你的类,它应该工作:

var actual = JsonConvert.DeserializeObject<TestClass>(serialized, new TestClassConverter());
Run Code Online (Sandbox Code Playgroud)