C# 如何反序列化可能是数组或单个对象的整个响应?

C# 如何反序列化可能是数组或单个对象的整个响应?,c#,.net,json,json.net,deserialization,C#,.net,Json,Json.net,Deserialization,我遇到的情况是,来自API的响应可以包含数组或单个项。但是,由于数组响应包含另一个嵌套对象,我正在努力进行响应的反序列化。以下是可以返回的不同响应(示例) 这是返回项目列表时的响应格式 { "data": { "items": [ { "id": 1 }, { "id": 2 } ] } } { "data": { "id": 1 } } 这是返回单个项时发

我遇到的情况是,来自API的响应可以包含数组或单个项。但是,由于数组响应包含另一个嵌套对象,我正在努力进行响应的反序列化。以下是可以返回的不同响应(示例)

这是返回项目列表时的响应格式

{
  "data": {
    "items": [
       {
          "id": 1
       },
       {
          "id": 2
       }
    ]
  }
}
{
  "data": {
    "id": 1
  }
}
这是返回单个项时发送的响应

{
  "data": {
    "items": [
       {
          "id": 1
       },
       {
          "id": 2
       }
    ]
  }
}
{
  "data": {
    "id": 1
  }
}
我最初尝试标准化响应时包括创建自定义转换器属性,但问题是您无法将通用参数传递给它。ReadJson的代码如下所示:

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

    return new List<T>() { token.ToObject<T>() };
}
public override object ReadJson(JsonReader reader,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
JToken令牌=JToken.Load(读卡器);
if(标记[“项”]?.Type==JTokenType.Array)
{
返回标记[“项”].ToObject();
}
返回新列表(){token.ToObject()};
}
这里是表示响应的类,但是我得到一个错误,泛型不能传递到属性中。进一步阅读后,这似乎是有意为之

public  class Response<T>
{
    [JsonProperty("version")]
    public string Version { get; set; }

    [JsonConverter(SingleOrArrayConverter<T>)]
    public T Data { get; set; }

    [JsonProperty("_links")]
    public Links Links { get; set; }
}
公共类响应
{
[JsonProperty(“版本”)]
公共字符串版本{get;set;}
[JsonConverter(单或阵列转换器)]
公共T数据{get;set;}
[JsonProperty(“_链接”)]
公共链接{get;set;}
}

有人对这个问题有其他想法/解决方案吗?

有以下几节课:

        public class Response
        {
            [JsonProperty("data")]
            public Data ResponseData { get; set; }
        }
        public class Data
        {
            [JsonProperty("id",NullValueHandling = NullValueHandling.Ignore)]
            public long? Id { get; set; }
            [JsonProperty("items", NullValueHandling = NullValueHandling.Ignore)]
            public List<Item> Items { get; set; }
        }
        public class Item
        {
            public long? Id { get; set; }
        }
公共类响应
{
[JsonProperty(“数据”)]
公共数据响应数据{get;set;}
}
公共类数据
{
[JsonProperty(“id”,NullValueHandling=NullValueHandling.Ignore)]
公共long?Id{get;set;}
[JsonProperty(“items”,NullValueHandling=NullValueHandling.Ignore)]
公共列表项{get;set;}
}
公共类项目
{
公共long?Id{get;set;}
}
然后反序列化响应,如下所示:

var responseObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Response>(responseString);
var responseObject=Newtonsoft.Json.JsonConvert.DeserializeObject(responseString);
要进一步改进对数据元素的访问,请在数据类中包含以下属性:

public List<Item> ResponseItems
            => Id != null
            ? new List<Item>(new Item[] { new Item { Id = Id} })
            : Items;
公共列表响应项
=>Id!=无效的
? 新列表(新项[]{new Item{Id=Id}})
:项目;

使响应一致将简化事情。始终返回数组,即使只有1个元素。您可以创建两个响应,一个使用数组,另一个使用单个对象。首先反序列化为
动态
对象,检查该对象是否为数组,然后反序列化为相应的类。相反,您可以使用
ToObject(Type)
。。。您必须将
public T Data
更改为
public List Data
。。。您可以从
objectType
中获得
T
是的,我同意archer的观点,为什么要制作一个返回类型不一致的API呢。为什么不做两个端点呢?