反序列化 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());
我正在尝试通过读取文件来反序列化 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());