C# 使用字段和字典反序列化json数组

C# 使用字段和字典反序列化json数组,c#,json,json.net,deserialization,C#,Json,Json.net,Deserialization,我想创建一个C#类来使用Newtonsoft.JSON反序列化这个JSON: [ { "awb": "2205900120010", "oras destinatar": "", "continut": "", "nume confirmare": "", "data confirmare": "", "ora confirmare": "", "awb retur": "",

我想创建一个C#类来使用Newtonsoft.JSON反序列化这个JSON:

[
    {
        "awb": "2205900120010",
        "oras destinatar": "",
        "continut": "",
        "nume confirmare": "",
        "data confirmare": "",
        "ora confirmare": "",
        "awb retur": "",
        "0": {
            "id": 0,
            "status": "AWB-ul nu a fost predat catre FAN Courier",
            "data": "",
            "ora": "",
            "oras": "",
            "traseu": ""
        }
    },
    {
        "awb": "5345899260009",
        "oras destinatar": "Tamaseu",
        "continut": "COMANDA 16201",
        "nume confirmare": "Szilagyi Ileana",
        "data confirmare": "13.12.2018",
        "ora confirmare": "17:16",
        "awb retur": "",
        "0": {
            "id": 1,
            "status": "Expeditie in livrare",
            "data": "12.12.2018",
            "ora": "14:46",
            "oras": "Lugoj",
            "traseu": "Expeditia a fost preluata de catre FAN Courier in data 12.12.2018 14:46."
        },
        "1": {
            "id": 1,
            "status": "Expeditie in livrare",
            "data": "12.12.2018",
            "ora": "19:35",
            "oras": "Lugoj",
            "traseu": "Expeditia a plecat din hub-ul FAN Courier Lugoj spre hub-ul de destinatie in data 12.12.2018 19:35."
        },
        "2": {
            "id": 2,
            "status": "Livrat",
            "data": "13.12.2018",
            "ora": "10:46",
            "oras": "Oradea",
            "traseu": "Expeditia a fost preluata spre livrare de catre curierul din orasul Oradea in data 13.12.2018 10:46."
        },
        "3": {
            "id": 2,
            "status": "Livrat",
            "data": "13.12.2018",
            "ora": "17:16",
            "oras": "Oradea",
            "traseu": "Ultimul status al expeditiei: livrat in data 13.12.2018 17:16."
        }
    }
]
已尝试使用反序列化

var list = JsonConvert.DeserializeObject<List<AwbTrackingResponse>>(text);

我希望
事件
字典也会被填充,但现在它仍然是空的。我不确定Newtonsoft.Json库是否支持这种类型的反序列化。如果是,那么也许我可以得到一个关于我的C#类需要更改的提示,如果不是,那么也许我可以得到一个替代方案,将这个JSON数据转换为可以从C#代码中使用。

您的JSON字符串有一些问题。 首先,在关键元素中有空格,例如

"data confirmare": "",
这应该是:

"data_confirmare": "",
使用json2sharp.com和jsonlint.com对其进行分类。 到目前为止,我有以下几点可以帮助您:

[{
    "awb": "2205900120010",
    "events": [{
        "0": {
            "id": 0,
            "status": "AWB-ul nu a fost predat catre FAN Courier"
        }
    }]

},
{
    "awb": "5345899260009",
    "oras_destinatar": "Tamaseu",
    "continut": "COMANDA 16201",
    "nume_confirmare": "Szilagyi Ileana",
    "data_confirmare": "13.12.2018",
    "ora_confirmare": "17:16",
    "awb_retur": "",
    "events": [{
            "0": {
                "id": 1,
                "status": "Expeditie in livrare",
                "data": "12.12.2018",
                "ora": "14:46",
                "oras": "Lugoj",
                "traseu": "Expeditia a fost preluata de catre FAN Courier in data 12.12.2018 14:46."
            }
        },
        {
            "1": {
                "id": 1,
                "status": "Expeditie in livrare",
                "data": "12.12.2018",
                "ora": "19:35",
                "oras": "Lugoj",
                "traseu": "Expeditia a plecat din hub-ul FAN Courier Lugoj spre hub-ul de destinatie in data 12.12.2018 19:35."
            }
        },
        {
            "2": {
                "id": 2,
                "status": "Livrat",
                "data": "13.12.2018",
                "ora": "10:46",
                "oras": "Oradea",
                "traseu": "Expeditia a fost preluata spre livrare de catre curierul din orasul Oradea in data 13.12.2018 10:46."
            }
        },
        {
            "3": {
                "id": 2,
                "status": "Livrat",
                "data": "13.12.2018",
                "ora": "17:16",
                "oras": "Oradea",
                "traseu": "Ultimul status al expeditiei: livrat in data 13.12.2018 17:16."
            }
        }
    ]
}
]Json.Net有一个“”功能,可以处理这种情况。如果使用
[JsonExtensionData]
属性标记字典,则该字典将填充JSON中未定义属性的键值对。问题是,字典必须声明为
dictionary
dictionary
。既然您想要
词典
,我建议您:

  • 在类中定义一个类型为
    Dictionary
    的私有
    EventData
    属性,从JSON中捕获额外数据,并用
    [JsonExtensionData]
    属性标记该属性
  • 更改public
    Events
    属性以将
    EventData
    字典转换为
    dictionary
    。用
    [JsonIgnore]
    标记此属性
  • 然后,只需像平常一样反序列化,它就可以按照您的意愿工作
  • 下面是它在代码中的外观:

    public class AwbTrackingResponse
    {
        ...
    
        [JsonExtensionData]
        private Dictionary<string, JToken> EventData { get; set; }
    
        [JsonIgnore]
        public Dictionary<int, AwbTrackingEvent> Events
        {
            get
            {
                return EventData?.ToDictionary(
                    kvp => Convert.ToInt32(kvp.Key), 
                    kvp => kvp.Value.ToObject<AwbTrackingEvent>()
                );
            }
            set
            {
                EventData = value?.ToDictionary(
                    kvp => kvp.Key.ToString(),
                    kvp => JToken.FromObject(kvp.Value)
                );
            }
        }
    }
    
    公共类AwbTrackingResponse
    {
    ...
    [JsonExtensionData]
    私有字典事件数据{get;set;}
    [JsonIgnore]
    公共词典事件
    {
    得到
    {
    返回EventData?.ToDictionary(
    kvp=>Convert.ToInt32(kvp.Key),
    
    kvp=>kvp.Value.ToObject

    我不确定是否有一种简单或干净的方法可以做到这一点。你可以用
    字典替换
    AwbTrackingResponse
    ,然后手动处理属性。或者更可能的是,你需要一个自定义转换器。是的,这解决了问题。我今天早上刚刚测试了它,工作正常。我很高兴JsNet处理此类json数据非常灵活。非常感谢Brianu,我无法控制json数据的生成方式。我只需要从我的C#代码中使用它,所以我一直在尝试寻找一个优雅的反序列化解决方案。
    public class AwbTrackingResponse
    {
        ...
    
        [JsonExtensionData]
        private Dictionary<string, JToken> EventData { get; set; }
    
        [JsonIgnore]
        public Dictionary<int, AwbTrackingEvent> Events
        {
            get
            {
                return EventData?.ToDictionary(
                    kvp => Convert.ToInt32(kvp.Key), 
                    kvp => kvp.Value.ToObject<AwbTrackingEvent>()
                );
            }
            set
            {
                EventData = value?.ToDictionary(
                    kvp => kvp.Key.ToString(),
                    kvp => JToken.FromObject(kvp.Value)
                );
            }
        }
    }