【发布时间】:2014-03-28 10:25:17
【问题描述】:
在某些情况下,当我收到其中一个数组属性为空的 JSON 时,反序列化失败,抛出以下异常:
无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型“SonicApi.ClickMark[]”,因为该类型需要 JSON 数组(例如 [1,2,3])正确反序列化。
要修复此错误,要么将 JSON 更改为 JSON 数组(例如 [1,2,3]),要么将反序列化类型更改为正常的 .NET 类型(例如,不是像整数这样的原始类型,而不是像数组或列表这样的集合类型)可以从 JSON 对象反序列化。也可以将 JsonObjectAttribute 添加到类型中以强制它从 JSON 对象反序列化。
路径 auftakt_result.click_marks,第 1 行,位置 121。
尝试使用以下代码忽略空值没有帮助:
var jsonSerializerSettings = new JsonSerializerSettings();
jsonSerializerSettings.NullValueHandling = NullValueHandling.Ignore;
这是一个产生错误的 JSON 示例:
{
"status": {
"code": 200
},
"auftakt_result": {
"clicks_per_bar": 0,
"overall_tempo": 0,
"overall_tempo_straight": 0,
"click_marks": {}
}
}
这里是一个 JSON 的例子,它的数组不为空并且不会产生任何错误:
{
"status": {
"code": 200
},
"auftakt_result": {
"clicks_per_bar": 8,
"overall_tempo": 144.886978,
"overall_tempo_straight": 144.90889,
"click_marks": [
{
"index": 0,
"bpm": 144.226624,
"probability": 0.828170717,
"time": 0.0787981859,
"downbeat": "false"
},
{
"index": 1,
"bpm": 144.226517,
"probability": 0.831781149,
"time": 0.286802721,
"downbeat": "false"
},
etc ...
以下是表示上述对象的 C# 类型:
public sealed class AnalyzeTempoResponse
{
[JsonProperty("auftakt_result")]
public AuftaktResult AuftaktResult { get; set; }
[JsonProperty("status")]
public Status Status { get; set; }
}
public sealed class Status
{
[JsonProperty("code")]
public int Code { get; set; }
}
public sealed class AuftaktResult
{
[JsonProperty("clicks_per_bar")]
public int ClicksPerBar { get; set; }
[JsonProperty("overall_tempo")]
public double OverallTempo { get; set; }
[JsonProperty("overall_tempo_straight")]
public double OverallTempoStraight { get; set; }
[JsonProperty("click_marks")]
public ClickMark[] ClickMarks { get; set; }
}
public sealed class ClickMark
{
[JsonProperty("index")]
public int Index { get; set; }
[JsonProperty("bpm")]
public double Bpm { get; set; }
[JsonProperty("probability")]
public double Probability { get; set; }
[JsonProperty("time")]
public double Time { get; set; }
[JsonProperty("downbeat")]
public string Downbeat { get; set; }
}
如何反序列化 click_marks 内容为空的响应?
如果这很重要,我使用的是最新版本的 Newtonsoft.Json : v6.0
编辑
这是根据@khillang 的回答采用的解决方案:
public class ClickMarkArrayConverter : CustomCreationConverter<ClickMark[]>
{
public override ClickMark[] Create(Type objectType)
{
return new ClickMark[] {};
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
{
return serializer.Deserialize(reader, objectType);
}
if (reader.TokenType == JsonToken.StartObject)
{
serializer.Deserialize(reader); // NOTE : value must be consumed otherwise an exception will be thrown
return null;
}
throw new NotSupportedException("Should not occur, check JSON for a new type of malformed syntax");
}
}
【问题讨论】:
-
我已经在底部添加了它:D
标签: c# arrays json exception deserialization