反序列化 JSON 并在响应中缺少 属性 名称

Deserializing JSON with Missing Property Names on Response

我正在尝试通过读取文件来反序列化 JSON。该文件将与我在以后的请求中收到的文件相同。我根据一些示例数据创建了 classes。但是,我 运行 遇到了 属性 名字的问题,这些名字没有出现在每个回复中。因此,我收到一个异常

"ArgumentException: Could not cast or convert from System.String to object" error.  

例如,下面是我正在尝试反序列化的 JSON 的示例。 我的 classes 是为此布局构建的

      "contents": [
        {
          "template": "paragraph",
          "title": null,
          "values": [
            {
              "name": null,
              "value": "paragraph of text"
            },
            {
              "name": null,
              "value": "paragraph of text"
            }
          ]
        }
]

不过有时我会收到这样的回复。

      "contents": [
        {
          "template": "paragraph",
          "title": null,
          "values": [
            "paragraph of text"
          ]
        }
]

注意 { } 和属性 "name" 和 "value" 是如何从 "values" 数组中消失的?

这是我的 class "contents" 数组

    public class Contents
    {
        public Contents()
        {
            Values = new List<TemplateValue>();
        }

        [JsonPropertyName("template")]
        public string Template { get; set; }

        [JsonPropertyName("title")]
        public string Title { get; set; }

        [JsonPropertyName("values")]
        public List<TemplateValue> Values { get; set; }
    }

    public class TemplateValue
    {
        [JsonPropertyName("name")]
        public string Name { get; set; }

        [JsonPropertyName("value")]
        public string Value { get; set; }
    }

这是我反序列化文件的方式

var jsonString = File.ReadAllText(_jsonFilelocation);
var jsonObject = JsonConvert.DeserializeObject<Contents>(jsonString);

如何调整我的代码来解决这种情况?在此先感谢您的帮助!

为您的 TemplateValue class 构建专用转换器:

public class TemplateValueConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(TemplateValue);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var token = JToken.Load(reader);
        var templateValue = new TemplateValue();
        if (token.Type == JTokenType.Object)
        {
            serializer.Populate(token.CreateReader(), templateValue);
        }
        else if (token.Type == JTokenType.String)
        {
            templateValue.Value = (string)token;
        }
        else
        {
            throw new JsonException($"Unexpected token type for TemplateValue: { token.Type.ToString() }");
        }
        return templateValue;
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary (would be neccesary if used for serialization)");
    }
}

...然后您可以处理两个 json:

var json1 = @"
[
    {
        ""template"": ""paragraph"",
        ""title"": null,
        ""values"": [{
            ""name"": null,
            ""value"": ""paragraph of text""
        }]
    }
]";
var json2 = @"
[
    {
        ""template"": ""paragraph"",
        ""title"": null,
        ""values"": [
            ""paragraph of text""
        ]
    }
]";
var contents1 = JsonConvert.DeserializeObject<Contents[]>(json1, new TemplateValueConverter());
var contents2 = JsonConvert.DeserializeObject<Contents[]>(json2, new TemplateValueConverter());