无法反序列化 JSON 对象

Cannot Deserialize JSON Object

我的问题是出现此错误

"Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) 到类型 'System.Collections.Generic.List`1[api.Controllers.Journey]' 因为该类型需要一个 JSON 数组(例如 [1,2,3])正确反序列化”...当我尝试序列化我的 API json 响应时。

API return 是这样的:

{
"Transport": [
    {
        "$id": "6",
        "SourceID": "1",
        "Context": "1",
        "Id": "AMADEUS#1",
        "Provider": null,
        "Journey": {
            "SourceID": "R1G0S0",
            "Duration": "42000",
            "Id": "5b6db9c6bfac4"
        }

    },
    {
        "$id": "7",
        "SourceID": "1",
        "Context": "1",
        "Id": "AMADEUS#1",
        "Provider": null,
        "Journey": [
            {
                "SourceID": "R1G0S0",
                "Duration": "42000",
                "Id": "5b6db9c6bfac4"
            },
            {
                "SourceID": "R1G0S1",
                "Duration": "42000",
                "Id": "5b6db9c6bsac4"
            }
        ]

    }
]
}

Journey 字段在第一个结果中是一个 JObject,但在第二个结果中是一个 JArray...

反序列化时出现错误:

Transport Transport = JsonConvert.DeserializeObject<Transport>(json_response);

我的 class 属性:

public class Transport{
    public string SourceID { get; set; }
    public string Context { get; set; }
    public string Id { get; set; }
    public ProviderOD Provider { get; set; }
    public Journey[] Journey { get; set; }
    public PriceOD Price { get; set; }
}
public class Journey
{
    public string Id { get; set; }
    public string SourceID { get; set; }
    public string Duration { get; set; }
}

我应该怎么做,动态设置 Journey[ ] 或 Journey ??

提前致谢...

你的class声明不对,必须用下面的来解码

TransportRootObject Transport = JsonConvert.DeserializeObject<TransportRootObject>(json_response);

和这个 class(es) 声明

public class TransportRootObject
{
    public List<Transport> Transport { get; set; }
}
public class Transport
{
    [JsonProperty("$id")]
    public string Id { get; set; }
    public string SourceID { get; set; }
    public string Context { get; set; }
    public string Id { get; set; }
    public ProviderOD Provider { get; set; }
    public List<Journey> Journey { get; set; }
}
public class Journey
{
    public string Id { get; set; }
    public string SourceID { get; set; }
    public string Duration { get; set; }
}

所以这里有一些问题。 JSON 中的顶级 Transport 对象实际上是一个传输对象数组。所以你需要一个额外的 class:

public class DocumentRoot
{
    public List<Transport> Transport { get; set; }
}

那么你想要:

var DocumentRoot = JsonConvert.DeserializeObject<DocumentRoot>(json_response);
//DocumentRoot.Transport is now a List<Transport> of your transport elements from the document.

在您的 JSON 中,其中一个成员名称是“$id”,这在 C# 中当然是无效的,因此要使其正常运行,您需要在您的 [JsonProperty(PropertyName = "$id")] 上添加一个属性Id 属性 告诉序列化程序名称。

我认为您的问题是您从 API 中 return 编辑的 JSON 格式不正确。如果 Journey 是一个数组,它应该总是 return 作为一个 array/list...如果只有 1 个则不是对象,如果有多个则应该是一个数组。

如果这是您无法修复的第三方 API,那么您的下一个选择是使用自定义转换器来处理像这样的奇怪格式 json。

我不记得我是在哪里找到原始 source/solution 的,但我会引导您完成这些步骤。

首先,您需要像这样创建一个新的 class。

public class SingleOrArrayConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(List<T>));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        if (token.Type == JTokenType.Array)
        {
            return token.ToObject<List<T>>();
        }
        return new List<T> { token.ToObject<T>() };
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

这是您的自定义转换器,用于处理 "sometimes array, sometimes object" 情况。它几乎只是做一个测试来确定它是一个数组还是一个对象并相应地处理。

然后,在您的交通工具 class 中,您将像这样在 Journey 数组 属性 上方添加属性。

[JsonConverter(typeof(SingleOrArrayConverter<Journey>))]
public List<Journey> Journey { get; set; }

这应该可以处理旅程以数组或对象的形式出现的情况。