如何在C#中使用动态和静态键名反序列化JSON

fPe*_*ecc 5 c# serialization json.net deserialization

我必须反序列化具有以下结构的api的响应:

[
  {
    "starttime": "...",
    "endtime": "....",
    "var1": {},
    "var2": {}
  },
  {
    "starttime": "...",
    "endtime": "....",
    "var1": {},
    "var3": {}
  },
  {
    "starttime": "...",
    "endtime": "....",
    "var1": {}
  }
] 
Run Code Online (Sandbox Code Playgroud)

一些见解:

  • JSON是一个对象数组
  • 数组中的每个对象将始终具有“ starttime”和“ endtime”属性
  • 对象“ var1”,“ var2”,“ var3”内部始终具有相同的属性……但是问题是对象键(var1,var2或var3)是动态的。它可以是任何字符串,并且此类对象的数量是动态的(我可以有3个或零个“ var”对象)。

我在想这样的事情,将JSON字符串反序列化为具有属性“ starttime”,“ endtime”的对象列表以及包含所有“ var”对象的字典。

public class MyResponse
{
    [JsonProperty(PropertyName = "starttime")]
    public string StartTime { get; set; }
    [JsonProperty(PropertyName = "endtime")]
    public string EndTime { get; set; }
    public Dictionary<string, VarObject> VarData { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是VarData属性始终为null。

有没有人尝试过这样的事情?

Dav*_*idG 4

您有两个选择,第一个是直接反序列化为 a List<Dictionary<string, object>>,例如:

var responses = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(json);
Run Code Online (Sandbox Code Playgroud)

或者,如果您坚持使用对象,则需要编写一个自定义转换器。例如,这样的事情:

public class MyResponseConverter : JsonConverter
{
    public override bool CanConvert(Type type) => type == typeof(MyResponse);

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var responseObject = JObject.Load(reader);

        MyResponse response = new MyResponse
        {
            StartTime = (string)responseObject["starttime"],
            EndTime = (string)responseObject["endtime"],
        };

        var varData = new Dictionary<string, object>();

        foreach (var property in responseObject.Properties())
        {
            if(property.Name == "starttime" || property.Name == "endtime")
            {
                continue;
            }

            varData.Add(property.Name, property.Value);
        }

        response.VarData = varData;
        return response;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // If you want to write to JSON, you will need to implement this method
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

你的班级会稍微改变一下:

[JsonConverter(typeof(MyResponseConverter))]
public class MyResponse
{
    [JsonProperty(PropertyName = "starttime")]
    public string StartTime { get; set; }
    [JsonProperty(PropertyName = "endtime")]
    public string EndTime { get; set; }

    public Dictionary<string, object> VarData { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在你像这样反序列化:

var responses = JsonConvert.DeserializeObject<List<MyResponse>>(json);
Run Code Online (Sandbox Code Playgroud)