在不知道类型的情况下将Json.NET对象转换为传统的.NET对象

时间:2016-04-16 02:42:33

标签: c# .net json json.net

如何将Json.NET对象转换为常规.NET类型(JArray of stringList<string>JTokenType=Integerint等等?)? 除了使用AutoMapperJToken.ToObject<T>的建议之外,我几乎找不到任何建议。 当在编译时知道JSON结构时,这是一个很好的建议,但是我不能创建一个表示未知数据的类,或者在我不知道底层类型时指定转换。 Json.NET没有“ConvertToWhateverIsProbablyMostAppropriate()”成员。 :)

那么为什么不只是枚举JWhatever个对象,让它们保持原样? 因为我无法将这些类型作为参数传递给(例如)Dapper,后者不知道来自spoo的JToken。

2 个答案:

答案 0 :(得分:3)

Charles&#39; /你的答案中不需要长时间的功能。只需使用通用ToObject函数并使用object类型参数。

完整示例:

using System;
using Newtonsoft.Json.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            string input = "Hello, world!";
            JToken token = JToken.FromObject(input);
            object output = token.ToObject<object>();
            Console.WriteLine(output);
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
}

那就是说,你应该知道它是什么类型,我真的不能想到你不知道它是什么类型的情况,并且可以&#39;在调用ToObject时,使用更具体的类型参数将其转换为更合适的内容。

答案 1 :(得分:2)

我编写了以下方法将JToken转换为旧的传统.NET类型。 这比我需要的更彻底(只处理几个JTokenTypes),但我为此答案扩展了它。

警告:这段代码未经测试,可能是针对不存在的问题的最糟糕方法的不良实现。

    /// <summary>Converts a Json.Net JToken to a boxed conventional .NET type (int, List, etc.)</summary>
    /// <param name="token">The JToken to evaluate</param>
    public object JTokenToConventionalDotNetObject(JToken token)
    {
        switch(token.Type) {
            case JTokenType.Object:
            return ((JObject)token).Properties()
                .ToDictionary(prop => prop.Name, prop => JTokenToConventionalDotNetObject(prop.Value));
            case JTokenType.Array:
            return token.Values().Select(JTokenToConventionalDotNetObject).ToList();
            default:
            return token.ToObject<object>();
        }
    }

为了处理JArrays,我原来的问题,Json.NET再次使任务变得简单:

    /// <summary>Converts a Json.NET JArray into a List of T where T is a conventional .NET type (int, string, etc.)</summary>
    /// <param name="jArray">Json.NET JArray to convert</param>
    public IList<object> JArrayToList(JArray jArray) {
        return (List<object>)jArray.ToObject(typeof(IList));
    }

输入类型:JArray的{​​{1}} Newtonsoft.Json.Linq.JValue JTokenType

输出:Integer其中每个对象的类型为List<object>

我认为Json.NET的System.Int64行为并不总是很明显。给定转换类型ToObject,它返回传统的.NET类型(<Object>long)或者什么也不做,例如获取并返回string,具体取决于JTokenType。

编辑:使用@ mason帮助的简化代码以及来自SO问题的代码,其中我的标记为重复。现在我更了解Json.NET的类型工作,我看到答案已经足够了。

答案之间的显着差异仅在于此代码处理嵌套数组/对象。