C# 确定json的通用方法是c中的数组或对象#

C# 确定json的通用方法是c中的数组或对象#,c#,json,C#,Json,我的项目包含太多对RESTAPI的调用,有时我得到json数组,有时得到json对象 当前,我必须为每个调用编写相同的重复代码,以确定响应json是数组还是对象 因此,我面临以下错误,因为我不知道传入的json类型 无法将当前JSON数组(例如[1,2,3])反序列化为类型“userList”,因为该类型需要JSON对象(例如{“name”:“value”})才能正确反序列化。要修复此错误,请将JSON更改为JSON对象(例如{“name”:“value”}),或将反序列化类型更改为数组或实现可

我的项目包含太多对RESTAPI的调用,有时我得到json数组,有时得到json对象

当前,我必须为每个调用编写相同的重复代码,以确定响应json是数组还是对象

因此,我面临以下错误,因为我不知道传入的json类型

无法将当前JSON数组(例如[1,2,3])反序列化为类型“userList”,因为该类型需要JSON对象(例如{“name”:“value”})才能正确反序列化。要修复此错误,请将JSON更改为JSON对象(例如{“name”:“value”}),或将反序列化类型更改为数组或实现可从JSON数组反序列化的集合接口(例如ICollection、IList)类似列表的类型。还可以将JsonArrayAttribute添加到类型中,以强制它从JSON数组反序列化

无法将当前JSON对象(例如{“名称”:“值”})反序列化为类型“System.Collections.Generic.List`1[MvcSumit1.Models.User]”,因为该类型需要JSON数组(例如[1,2,3])才能正确反序列化。若要修复此错误,请将JSON更改为JSON数组(例如[1,2,3]),或更改反序列化类型,使其成为可以从JSON对象反序列化的正常.NET类型(例如,不是integer之类的基元类型,也不是数组或列表之类的集合类型)。还可以将JsonObjectAttribute添加到类型中,以强制它从JSON对象反序列化

所以为了解决这个问题,我需要一个通用的方法来处理上述两种情况

我想要一个能处理以上两种情况的通用方法

下面的通用方法可以将传入的json解析为
对象
列表

输出:

1) 通过将json与对象数组一起使用

string json1 = @"[{'Id':'1','Name':'Mike','Age':43},{'Id':'2','Name':'Anna','Age':56}]";

2) 通过仅对对象使用json

string json2 = @"{'Id':'3','Name':'John','Age':24}";


备选方案

下面的通用方法可以将传入的json解析为
对象
列表
,并返回
列表

公共类实用程序
{
公共静态列表JsonParser(字符串json)
{
JToken JToken=JToken.Parse(json);
如果(jToken是JArray)
{
返回jToken.ToObject();
}
否则如果(jToken是JObject)
{
List lst=新列表();
lst.Add(jToken.ToObject());
返回lst;
}
其他的
返回新列表();
}
}
您可以使用上面的通用方法,如下所示

class Program
{
    static void Main(string[] args)
    {
        var userList = Utility.JsonParser<User>("You json either object or array");

        if (userList.Count > 0)
        {
            userList.ForEach(user => Console.WriteLine($"Id: {user.Id},  Name: {user.Name}, Age: {user.Age}"));
        }
        else
        {
            //Do code here if your list is empty
        }

        Console.ReadLine();
    }
}
类程序
{
静态void Main(字符串[]参数)
{
var userList=Utility.JsonParser(“您可以使用json对象或数组”);
如果(userList.Count>0)
{
userList.ForEach(user=>Console.WriteLine($“Id:{user.Id},Name:{user.Name},Age:{user.Age}”);
}
其他的
{
//如果列表为空,请在此处进行编码
}
Console.ReadLine();
}
}

如果我们必须处理不同的类型,而不仅仅是通过
数组
对象
,以下是我的方法: (注意我使用的是Newtonsoft.Json)

方法1

public bool TryDeserialize(string json, out object target, params Type[] types)
{            
    foreach (Type type in types)
    {
        try
        {
            target = JsonConvert.DeserializeObject(json, type);
            return true;
        }
        catch (Exception)
        {                    
        }
    }
    target = null;
    return false;
}
然后像这样使用它:

 object obj = null;
 Type[] types = new Type[] { typeof(TypeA), typeof(List<TypeB>) };

 if (TryDeserialize(json, out obj, types))
 {
     if (obj is TypeA)
     {
         var r = obj as TypeA;
     }
     else
     {
         var r = obj as List<TypeB>;
     }
 }
object obj = null;
if (TryDeserialize<TypeA, List<TypeB>>(json, out obj))
{
    if (obj is TypeA)
    {
        var r = obj as TypeA;
    }
    else
    {
        var r = obj as List<TypeB>;
    }
}
objectobj=null;
类型[]类型=新类型[]{typeof(TypeA),typeof(List)};
if(TryDeserialize(json、out obj、类型))
{
if(obj为A型)
{
var r=A类的obj;
}
其他的
{
var r=obj as列表;
}
}
方法2

public bool TryDeserialize<T1, T2>(string json, out object target)
{            

    try
    {
        target = JsonConvert.DeserializeObject<T1>(json);
        return true;
    }
    catch (Exception)
    {
    }

    try
    {
        target = JsonConvert.DeserializeObject<T2>(json);
        return true;
    }
    catch (Exception)
    {
        target = null;
        return false;
    }
}
public bool TryDeserialize(字符串json,out对象目标)
{            
尝试
{
target=JsonConvert.DeserializeObject(json);
返回true;
}
捕获(例外)
{
}
尝试
{
target=JsonConvert.DeserializeObject(json);
返回true;
}
捕获(例外)
{
target=null;
返回false;
}
}
然后像这样使用它:

 object obj = null;
 Type[] types = new Type[] { typeof(TypeA), typeof(List<TypeB>) };

 if (TryDeserialize(json, out obj, types))
 {
     if (obj is TypeA)
     {
         var r = obj as TypeA;
     }
     else
     {
         var r = obj as List<TypeB>;
     }
 }
object obj = null;
if (TryDeserialize<TypeA, List<TypeB>>(json, out obj))
{
    if (obj is TypeA)
    {
        var r = obj as TypeA;
    }
    else
    {
        var r = obj as List<TypeB>;
    }
}
objectobj=null;
if(TryDeserialize(json,out obj))
{
if(obj为A型)
{
var r=A类的obj;
}
其他的
{
var r=obj as列表;
}
}

据我所知,C#不支持JSON(理解其含义:框架中没有JSON库构建)。至少写下您使用的JSON库的类型。(在我使用的JSON库中,你永远不会看到这个错误。)可能是重复的,你能检查一下这个@Julo我使用了Newtonsoft.JSON。@KarthickTrichyChandrasekaran,我想要泛型方法,这样我就可以只传递类型,它会给我一个结果。这是我一直在寻找的,谢谢它工作,它解决了我的问题:)这是我的意见,该方法应返回
List
。它应该在内部反序列化单个对象,然后将其放入一个列表中,返回一个包含1个元素的列表。由于调用者无论如何都需要处理列表场景,这实际上取决于调用者是否需要知道json是否包含单个对象或包含单个对象的数组。如果这不重要,我会返回
列表
而不是
对象
@LasseVågsætherKarlsen,谢谢你的建议,只要有足够的时间,我一定会更新我的答案,再次感谢:)
public bool TryDeserialize<T1, T2>(string json, out object target)
{            

    try
    {
        target = JsonConvert.DeserializeObject<T1>(json);
        return true;
    }
    catch (Exception)
    {
    }

    try
    {
        target = JsonConvert.DeserializeObject<T2>(json);
        return true;
    }
    catch (Exception)
    {
        target = null;
        return false;
    }
}
object obj = null;
if (TryDeserialize<TypeA, List<TypeB>>(json, out obj))
{
    if (obj is TypeA)
    {
        var r = obj as TypeA;
    }
    else
    {
        var r = obj as List<TypeB>;
    }
}