确定json是c#

时间:2018-09-27 06:21:50

标签: c# json

我的项目包含过多的对rest api的调用,有时我得到json数组和有时json对象。

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

所以我遇到以下错误,因为我不知道传入的json类型。

  

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

OR

  

无法将当前JSON对象(例如{“ name”:“ value”})反序列化为类型'System.Collections.Generic.List`1 [MvcSumit1.Models.User]',因为该类型需要JSON数组(例如[1,2,3])正确反序列化。要解决此错误,可以将JSON更改为JSON数组(例如[1,2,3]),也可以更改反序列化类型,使其成为普通的.NET类型(例如,不像整数这样的原始类型,也不像这样的集合类型数组或列表),可以从JSON对象反序列化。还可以将JsonObjectAttribute添加到类型中,以强制其从JSON对象反序列化。

因此,要摆脱这个问题,我想要可以同时处理上述两种情况的通用方法。

2 个答案:

答案 0 :(得分:2)

  

我想要可以处理以上两种情况的通用方法。

下面的通用方法可以将传入的json解析为objectList<object>

public class Utility
{
    public static object JsonParser<T>(string json)
    {
        try
        {
            JToken jToken = JToken.Parse(json);

            if (jToken is JArray)
                return jToken.ToObject<List<T>>();
            else if (jToken is JObject)
                return jToken.ToObject<T>();
            else
                return "Unable to cast json to unknown type";
        }
        catch (JsonReaderException jex)
        {
            return jex.Message;
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
    }
}

您可以使用上述通用方法,如下所示。我创建了一个控制台应用程序供您演示。

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

        if (result is List<User>)
        {
            var userList = result as List<User>;
            userList.ForEach(user => Console.WriteLine($"Id: {user.Id},  Name: {user.Name}, Age: {user.Age}"));
        }
        else if (result is User)
        {
            var user = result as User;
            Console.WriteLine($"Id: {user.Id},  Name: {user.Name}, Age: {user.Age}");
        }
        else if (result is string)
        {
            Console.WriteLine(result);
        }

        Console.ReadLine();
    }
}

样本类用于反序列化您的json。

public class User
{
    public string Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

输出:

1)通过将json与对象数组结合使用

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

source

2)通过仅将json与对象配合使用。

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

enter image description here


替代

下面的通用方法可以将传入的json解析为objectList<object>并返回List<object>

public class Utility
{
    public static List<T> JsonParser<T>(string json)
    {
        JToken jToken = JToken.Parse(json);

        if (jToken is JArray)
        {
            return jToken.ToObject<List<T>>();
        }
        else if (jToken is JObject)
        {
            List<T> lst = new List<T>();
            lst.Add(jToken.ToObject<T>());
            return lst;
        }
        else
            return new List<T>();
    }
}

您可以使用上述通用方法,如下所示。

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

答案 1 :(得分:0)

如果我们不仅要用Arrayobject来处理不同的类型,下面是我的方法: (请注意我是using 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>;
     }
 }

方法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;
    }
}

并像这样使用它:

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