Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用不同的数据结构反序列化JSON_C#_Json_Json.net_Zoho - Fatal编程技术网

C# 使用不同的数据结构反序列化JSON

C# 使用不同的数据结构反序列化JSON,c#,json,json.net,zoho,C#,Json,Json.net,Zoho,我正在使用的一个JSON API返回的响应根据查询返回的结果的多少而改变其数据结构。我从C#中使用它,并使用JSON.NET对响应进行反序列化 下面是从API返回的JSON 多结果响应: { "response": { "result": { "Leads": { "row": [ { "no": "1", ... ... ... { "response": { "result": {

我正在使用的一个JSON API返回的响应根据查询返回的结果的多少而改变其数据结构。我从C#中使用它,并使用JSON.NET对响应进行反序列化

下面是从API返回的JSON

多结果响应:

{
  "response": {
    "result": {
      "Leads": {
        "row": [
          {
            "no": "1",
...
...
...
{
  "response": {
    "result": {
      "Leads": {
        "row": {
          "no": "1",
...
...
...
public class ZohoLeadResponseRootJson
{
    public ZohoLeadResponseJson Response { get; set; }
}

public class ZohoLeadResponseJson
{
    public ZohoLeadResultJson Result { get; set; }
}

public class ZohoLeadResultJson
{
    public ZohoDataMultiRowJson Leads { get; set; }
}

public class ZohoDataMultiRowJson
{
    public List<ZohoDataRowJson> Row { get; set; }
}

public class ZohoDataRowJson
{
    public int No { get; set; }
    ...
}
单一结果响应:

{
  "response": {
    "result": {
      "Leads": {
        "row": [
          {
            "no": "1",
...
...
...
{
  "response": {
    "result": {
      "Leads": {
        "row": {
          "no": "1",
...
...
...
public class ZohoLeadResponseRootJson
{
    public ZohoLeadResponseJson Response { get; set; }
}

public class ZohoLeadResponseJson
{
    public ZohoLeadResultJson Result { get; set; }
}

public class ZohoLeadResultJson
{
    public ZohoDataMultiRowJson Leads { get; set; }
}

public class ZohoDataMultiRowJson
{
    public List<ZohoDataRowJson> Row { get; set; }
}

public class ZohoDataRowJson
{
    public int No { get; set; }
    ...
}
请注意“row”节点的区别,在多个结果的情况下它是一个数组,在单个结果的情况下它是一个对象

下面是我用来反序列化这些数据的类

课程:

{
  "response": {
    "result": {
      "Leads": {
        "row": [
          {
            "no": "1",
...
...
...
{
  "response": {
    "result": {
      "Leads": {
        "row": {
          "no": "1",
...
...
...
public class ZohoLeadResponseRootJson
{
    public ZohoLeadResponseJson Response { get; set; }
}

public class ZohoLeadResponseJson
{
    public ZohoLeadResultJson Result { get; set; }
}

public class ZohoLeadResultJson
{
    public ZohoDataMultiRowJson Leads { get; set; }
}

public class ZohoDataMultiRowJson
{
    public List<ZohoDataRowJson> Row { get; set; }
}

public class ZohoDataRowJson
{
    public int No { get; set; }
    ...
}
公共类ZohoLeadResponseRootJson
{
公共zoholeadsresponsejson响应{get;set;}
}
公共类ZohoLeadResponseJson
{
public zoholeadsultjson结果{get;set;}
}
公共类ZohoLeadResultJson
{
公共ZohoDataMultiRowJson引线{get;set;}
}
公共类ZohoDataMultiRowJson
{
公共列表行{get;set;}
}
公共类ZohoDataRowJson
{
公共int No{get;set;}
...
}
“多结果响应”是反序列化的,没有任何问题,但是当响应中只有一个结果时,由于数据结构更改,响应无法反序列化。我有个例外

Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON 
object (e.g. {"name":"value"}) into type 
'System.Collections.Generic.List`1[MyNamespace.ZohoDataRowJson]' 
because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) 
or change the deserialized type so that it is a normal .NET type (e.g. not a 
primitive type like integer, not a collection type like an array or List<T>) 
that can be deserialized from a JSON object. JsonObjectAttribute can also be 
added to the type to force it to deserialize from a JSON object.

Path 'response.result.Notes.row.no', line 1, position 44.
Newtonsoft.Json.JsonSerializationException:无法反序列化当前Json
对象(例如{“名称”:“值”})转换为类型
'System.Collections.Generic.List'1[MyNamespace.ZohoDataRowJson]'
因为该类型需要一个JSON数组(例如[1,2,3])才能正确反序列化。
要修复此错误,请将JSON更改为JSON数组(例如[1,2,3])
或者更改反序列化类型,使其成为正常的.NET类型(例如,不是
基本类型(如整数,而不是数组或列表等集合类型)
可以从JSON对象反序列化的。JsonObjectAttribute也可以是
添加到类型以强制其从JSON对象反序列化。
路径“response.result.Notes.row.no”,第1行,位置44。
在Json.Net中,有没有一种方法可以处理这个问题,它有一些属性,并且希望不必编写转换器?

这个方法的灵感来源于一个类似的问题

public class ZohoDataMultiRowJson
{
    [JsonConverter(typeof(ArrayOrObjectConverter<ZohoDataRowJson>))]
    public List<ZohoDataRowJson> Row { get; set; }
}

public class ArrayOrObjectConverter<T> : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartArray)
        {
            return serializer.Deserialize<List<T>>(reader);
        }
        else if (reader.TokenType == JsonToken.StartObject)
        {
            return new List<T>
            {
                (T) serializer.Deserialize<T>(reader)
            };
        }
        else
        {
            throw new NotSupportedException("Unexpected JSON to deserialize");
        }
    }

    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }
}
公共类ZohoDataMultiRowJson
{
[JsonConverter(类型(ArrayOrObjectConverter))]
公共列表行{get;set;}
}
公共类ArrayOrObjectConverter:JsonConverter
{
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
if(reader.TokenType==JsonToken.StartArray)
{
返回序列化程序。反序列化(读取器);
}
else if(reader.TokenType==JsonToken.StartObject)
{
返回新列表
{
(T) 序列化程序。反序列化(读取器)
};
}
其他的
{
抛出新的NotSupportedException(“要反序列化的意外JSON”);
}
}
公共覆盖布尔CanConvert(类型objectType)
{
抛出新的NotImplementedException();
}
}

感谢@L.B的链接和链接问题的答案。ReadJson方法reader.ValueType中的另一个类似问题@L.B.始终为空。在本例中,我必须使用reader.TokenType,即StartArray或StartObject。此外,在这两种情况下,反序列化将继续进行。我想发布一个答案,因为它与两个链接的答案没有什么不同。我还想说出供应商的名字,这样可以帮助将来的用户遇到同样的问题。我重新打开了这个问题…谢谢@L.B。添加了答案。让答案更通用,而不仅仅是针对ZohoDataRowJson,怎么样?那样就完美了。顺便说一句,a+1有意义。更新。谢谢你的+1。