在不知道类型的情况下,将Json.NET对象转换为常规.NET对象

本文关键字:对象 NET 转换 常规 Json 类型 不知道 情况下 | 更新日期: 2024-09-25 18:21:00

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

那么,为什么不直接枚举JWhatever对象,让它们保持原样呢?因为我不能将这些类型作为参数传递给Dapper,它不知道JToken和spoo。

在不知道类型的情况下,将Json.NET对象转换为常规.NET对象

Charles的答案中不需要长函数。只需使用通用的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();
        }
    }
}

也就是说,您应该知道它是什么类型,我真的想不出有什么情况下您不知道它是哪种类型,并且无法在对ToObject的调用中使用更具体的类型参数将其转换为更合适的类型。

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

Caveat discipulus:此代码未经测试,可能是对不存在的问题的最糟糕方法的糟糕实现。

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

输入类型:Newtonsoft.Json.Linq.JValueJArrayIntegerJTokenType

输出:List<object>,其中每个对象的类型为System.Int64

我相信Json.NET的ToObject行为并不总是显而易见的。给定转换类型<Object>,它要么返回传统的.NET类型(longstring),要么什么都不做,例如根据JTokenType获取并返回Newtonsoft.Json.Linq.JArray


编辑:在@mason的帮助下简化代码,并使用SO问题中的代码,我的代码被标记为重复。现在我更好地理解了Json.NET的类型工作,我认为这个答案已经足够了。

答案之间的显著区别只是此代码处理嵌套的数组/对象。