简体   繁体   English

Json.net没有反序列化对象列表

[英]Json.net is not deserializing a list of object

I have the following model structure : 我有以下模型结构:

public class Step : ActivityElement
{
    public Step()
    {
        this.Id = Guid.NewGuid();
        this.Label = "Basic Step";
        this.Type = "step";
    }

    public Guid Id { get; set; }
    public string Label { get; set; }
    public Input Input { get; set; }
}

public abstract class Input
{
    public string Type { get; set; }
    public object Value { get; set; }
}

public class GridInput : Input
{
    public GridInput()
    {
        this.Type = "grid";
        this.GridHeader = new GridHeader();
        this.RowList = new List<GridRow>();
    }

    public GridHeader GridHeader { get; set; }
    public List<GridRow> RowList { get; set; }
}

public class GridRow
{
    public GridRow()
    {
        this.IsDeleted = false;
        this.CellList = new List<GridCell>();
    }

    public List<GridCell> CellList { get; set; }
    public bool IsDeleted { get; set; }
}

public class GridCell
{
    public GridCell()
    {
        this.name = "not set yet";
        this.Input = null;
    }

    public string name { get; set; }
    public Input Input { get; set; }
}

Here is the JSON that I am trying to deserialize 这是我要反序列化的JSON

{
    "Id":"e833ceae-57e5-4c52-8d56-b047790cb7c7",
    "Label":"Grid time!",
    "Input":
    {
        "GridHeader":{"ColumnDefinitionList":[{"field":"column1","title":"Column 1"},{"field":"column2","title":"Column 2"},{"field":"column3","title":"Column 3"},{"field":"column4","title":"Column 4"}]},
        "RowList":
        [
            {
                "CellList":
                [
                    {"name":"column1","Input":{"Type":"text","Value":"cell 1 row 1"}},
                    {"name":"column2","Input":{"Type":"text","Value":"cell 2 row 1"}},
                    {"name":"column3","Input":{"Type":"text","Value":"cell 3 row 1"}},
                    {"name":"column4","Input":{"Type":"text","Value":"cell 4 row 1"}}
                ],
                "IsDeleted":false
            },
            {
                "CellList":
                [
                    {"name":"column1","Input":{"Type":"text","Value":"cell 1 row 2"}},
                    {"name":"column2","Input":{"Type":"text","Value":"cell 2 row 2"}},
                    {"name":"column3","Input":{"Type":"text","Value":"cell 3 row 2"}},
                    {"name":"column4","Input":{"Type":"text","Value":"cell 4 row 2"}}
                ],
                "IsDeleted":false
            }
        ],
        "Type":"grid",
        "Value":null
    },
    "DisplayPosition":2,
    "Type":"step"
}

Here is the custom deserializer that makes sure the GridInput is the object created as the Input : 这是确保GridInput是作为Input创建的对象的自定义反序列化器:

public abstract class JsonCreationConverter<T> : JsonConverter
{
    protected abstract T Create(Type objectType, JObject jObject);

    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // Load JObject from stream
        JObject jObject = JObject.Load(reader);

        // Create target object based on JObject
        T target = Create(objectType, jObject);

        // Populate the object properties
        serializer.Populate(jObject.CreateReader(), target);

        return target;
    }
}
public class InputJsonConverter : JsonCreationConverter<Input>
{
    protected override Input Create(Type objectType, JObject jObject)
    {
        var type = (string)jObject.Property("Type");
        switch (type)
        {
            case "grid":
                return new GridInput();
            case "text":
                return new TextInput();
            case "dropdown":
                return new DropdownInput();
            case "checkbox":
                return new CheckboxInput();
        }

        throw new ApplicationException(String.Format("The given type {0} is not supported!", type));
    }
}

I have implemented something so that the GridHeader is skiped (I dont need it to be deserialized, so it simply create an empty GridHeader during the deserializing process), but the RowList end up being always empty after the GridInput is deserialized. 我已经实现了一些方法,以便跳过GridHeader(我不需要对其进行反序列化,因此只需在反序列化过程中创建一个空的GridHeader), 但是在对GridInput进行反序列化后, RowList最终始终为空 I have tried multiple things, but I am running out of idea... 我已经尝试了多种方法,但是我的想法已经耗尽了。

TL:DR: The GridInput is created but the RowList is empty TL:DR:创建GridInput,但RowList为空

I can't reproduce the problem. 我无法重现该问题。 Is it possible that you forgot to have Json.NET use the InputJsonConverter class? 您是否有可能忘记让Json.NET使用InputJsonConverter类? The following code works. 以下代码有效。

void Main()
{
    var step = JsonConvert.DeserializeObject<Step>(s);
    Console.WriteLine(((GridInput)step.Input).RowList.Count); // 2
}
public class GridHeader { }
public class ActivityElement { public string Type { get; set; } }
public class Step : ActivityElement
{
    public Step()
    {
        this.Id = Guid.NewGuid();
        this.Label = "Basic Step";
        this.Type = "step";
    }

    public Guid Id { get; set; }
    public string Label { get; set; }
    public Input Input { get; set; }
}
[JsonConverter(typeof(InputJsonConverter))]
public abstract class Input
{
    public string Type { get; set; }
    public object Value { get; set; }
}

public class TextInput : Input
{
    public TextInput()
    {
        this.Type = "text";
    }
}
public class GridInput : Input
{
    public GridInput()
    {
        this.Type = "grid";
        this.GridHeader = new GridHeader();
        this.RowList = new List<GridRow>();
    }

    public GridHeader GridHeader { get; set; }
    public List<GridRow> RowList { get; set; }
}

public class GridRow
{
    public GridRow()
    {
        this.IsDeleted = false;
        this.CellList = new List<GridCell>();
    }

    public List<GridCell> CellList { get; set; }
    public bool IsDeleted { get; set; }
}

public class GridCell
{
    public GridCell()
    {
        this.name = "not set yet";
        this.Input = null;
    }

    public string name { get; set; }
    public Input Input { get; set; }
}
public abstract class JsonCreationConverter<T> : JsonConverter
{
    protected abstract T Create(Type objectType, JObject jObject);

    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // Load JObject from stream
        JObject jObject = JObject.Load(reader);

        // Create target object based on JObject
        T target = Create(objectType, jObject);

        // Populate the object properties
        serializer.Populate(jObject.CreateReader(), target);

        return target;
    }
    public override void WriteJson(
    JsonWriter writer,
    Object value,
    JsonSerializer serializer
)
    {
        throw new NotImplementedException();
    }
}
public class InputJsonConverter : JsonCreationConverter<Input>
{
    protected override Input Create(Type objectType, JObject jObject)
    {
        var type = (string)jObject.Property("Type");
        switch (type)
        {
            case "grid":
                return new GridInput();
            case "text":
                return new TextInput();
//            case "dropdown":
//                return new DropdownInput();
//            case "checkbox":
//                return new CheckboxInput();
        }

        throw new ApplicationException(String.Format("The given type {0} is not supported!", type));
    }
}
string s = @"{
    ""Id"":""e833ceae-57e5-4c52-8d56-b047790cb7c7"",
    ""Label"":""Grid time!"",
    ""Input"":
    {
        ""GridHeader"":{""ColumnDefinitionList"":[{""field"":""column1"",""title"":""Column 1""},{""field"":""column2"",""title"":""Column 2""},{""field"":""column3"",""title"":""Column 3""},{""field"":""column4"",""title"":""Column 4""}]},
        ""RowList"":
        [
            {
                ""CellList"":
                [
                    {""name"":""column1"",""Input"":{""Type"":""text"",""Value"":""cell 1 row 1""}},
                    {""name"":""column2"",""Input"":{""Type"":""text"",""Value"":""cell 2 row 1""}},
                    {""name"":""column3"",""Input"":{""Type"":""text"",""Value"":""cell 3 row 1""}},
                    {""name"":""column4"",""Input"":{""Type"":""text"",""Value"":""cell 4 row 1""}}
                ],
                ""IsDeleted"":false
            },
            {
                ""CellList"":
                [
                    {""name"":""column1"",""Input"":{""Type"":""text"",""Value"":""cell 1 row 2""}},
                    {""name"":""column2"",""Input"":{""Type"":""text"",""Value"":""cell 2 row 2""}},
                    {""name"":""column3"",""Input"":{""Type"":""text"",""Value"":""cell 3 row 2""}},
                    {""name"":""column4"",""Input"":{""Type"":""text"",""Value"":""cell 4 row 2""}}
                ],
                ""IsDeleted"":false
            }
        ],
        ""Type"":""grid"",
        ""Value"":null
    },
    ""DisplayPosition"":2,
    ""Type"":""step""
}";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM