将Json.NET对象转换为传统的.NET对象,而不知道类型

如何将Json.NET对象转换为传统的.NET类型( JArray of string to ListJTokenType=Integer to int等)? 我发现使用AutoMapperJToken.ToObject建议很少。 当在编译时知道JSON结构时,这是一个很好的建议,但是我不能创建一个表示未知数据的类,或者在我不知道底层类型时指定转换。 Json.NET没有“ConvertToWhateverIsProbablyMostAppropriate()”成员。 🙂

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

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(); Console.WriteLine(output); Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } } 

也就是说,你应该知道它是什么类型,我真的不能想到你不知道它是什么类型的情况,并且无法通过调用中更具体的类型参数将其转换为更合适的类型to ToObject

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

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

  /// Converts a Json.Net JToken to a boxed conventional .NET type (int, List, etc.) /// The JToken to evaluate 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(); } } 

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

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

输入类型:带有Integer JTokenTypeJArrayJTokenType

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

我相信Json.NET的ToObject行为并不总是很明显。 给定转换类型 ,它返回传统的.NET类型( longstring )或者什么都不做,例如获取并返回Newtonsoft.Json.Linq.JArray ,具体取决于JTokenType。


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

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