gpt4 book ai didi

c# - 仅当数组为空时 JSON 反序列化才会失败

转载 作者:行者123 更新时间:2023-12-02 20:30:11 25 4
gpt4 key购买 nike

在某些情况下,当我收到数组属性之一为空的 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 内容为 null 的响应?

如果这很重要,我正在使用最新版本的 Newtonsoft.Json:v6.0

编辑

这是根据@khellang的回答采用的解决方案:

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");
}
}

最佳答案

它与 null 值无关(您的 JSON 示例中没有任何 任何 属性具有 null 值)。您正在尝试将 JSON 对象反序列化为 ClickMark[]:

"click_marks": {} // <-- This is an object, not null, not an array.

它起作用的第二个原因是 click_marks 属性实际上ClickMark 对象的数组:

"click_marks": [{...}, {...}, {...}] // <-- This is an array with three objects.

数据从哪里来?您需要确保 click_marks 属性是数组或对象,而不是两者,并且您键入的 C# 对象 ClickMarks 与 JSON 属性的“类型”匹配.

如果您无法控制数据,例如如果它来自第 3 方,我建议您编写一个可应用于该单个属性的自定义 JsonConverter:

public class ObjectToArrayConverter<T> : CustomCreationConverter<T[]>
{
public override T[] Create(Type objectType)
{
return new T[0];
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
{
return serializer.Deserialize(reader, objectType);
}
else
{
return new T[] { serializer.Deserialize<T>(reader) };
}
}
}

并像这样应用它:

public sealed class AuftaktResult
{
// ...

[JsonProperty("click_marks")]
[JsonConverter(typeof(ObjectToArrayConverter<ClickMark>))]
public ClickMark[] ClickMarks { get; set; }
}

这将检查该值是否是单个对象并将其包装在一个数组中,以便它与您的 C# POCO 属性匹配:)

关于c# - 仅当数组为空时 JSON 反序列化才会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22027041/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com