如何在 C# 中动态转换来自 Json.NET 的解析 JSON 结果?

Posted

技术标签:

【中文标题】如何在 C# 中动态转换来自 Json.NET 的解析 JSON 结果?【英文标题】:How to convert dynamically in C# the parsed JSON result from Json.NET? 【发布时间】:2017-07-17 07:39:56 【问题描述】:

我已经用 Json.NET 实现了一个 JSON-RPC。我转换的响应结果:

T data = ((JToken)value).ToObject<T>();

如果结果是一个对象,这项工作。但如果结果是 Int64 之类的原语或字符串,则它不起作用。那么这个值就不是 JToken。

我找到了方法:

static object Convert(object initialValue, CultureInfo culture, Type targetType)

这似乎可以完成所需的工作。但是 ConvertUtils 类是内部的。是否有任何公共方法可以将任何解析的 JSON 结果转换为任何目标类型?

更完整的 JSON-RPC 处理示例:

JsonRpcResult result = serializer.Deserialize<JsonRpcResult>(jsonTextReader);
Type type = requests[result.id];
object value = result.result;
return ((JToken)value).ToObject(type);

一个典型的 JSON 字符串:

"jsonrpc":"2.0","result":DynamicValidJsonDependsOnID,"id":1

DynamicValidJsonDependsOnID 的 JSON 内容取决于 id,可以是任何有效的 JSON。没有限制。

JsonRpcResult 类:

[JsonObject(MemberSerialization.Fields)]
internal class JsonRpcResult

    private string jsonrpc;
    private object result;
    private Dictionary<String,Object> error;
    private object id;
 

【问题讨论】:

如何使用Newtonsoft.Json.Linq.JObject.Parse(string json) 不确定我是否理解您的要求。你在找Convert.ChangeType()吗? @IswarKChettri JSON 已经被解析,我已经有一个 JObject。但也可以是 Int64 或 null。请参阅更详细的示例。我可以在完全解析后转换结果,因为我首先需要响应的“id”。 @dbc 是的,我搜索了一些东西,但它还必须转换 JObject、JArray 以及 json 解析器可以返回的所有内容。 @Horcrux7 - 你不能只检查if (value is JToken),如果是,使用ToObject(),但如果不是,使用Convert.ChangeType() 【参考方案1】:

当您反序列化 JsonRpcResult 对象时,您的 object result 字段将是复杂对象或原始类型。

因此,如果它是原始类型(例如 Int32),result.result 将包含直接值而不是 JToken

所以,我首先要检查Type 是否像这样原始:

JsonRpcResult result = serializer.Deserialize<JsonRpcResult>(jsonTextReader);
Type type = requests[result.id];
object value = result.result;

if (!type.IsPrimitive && type != typeof(decimal) && type != typeof(string) && type != typeof(DateTime))
    return ((JToken)value).ToObject(type);
return value; //otherwise return the value as it is without parsing.

编辑

当您在运行时获得Types 时,您不能将您的objects 转换为正确的Type。您也必须使用其他答案中提到的 dynamic 关键字,或者检查对象的 Type 是否是您想要的类型并像这样进行转换:

if (type == typeof(string))

    string str = (string)returnedValue;
    ...

【讨论】:

【参考方案2】:

这样使用Newtonsoft.Json.Jobject.Parse怎么样

 //==== Create class for your Json attributes
 string jsonData= "  \"Employee":\"name\":\"John\", \"age\":31, \"city\":\"New York\" ";
 YourJsonClass obj= new YourJsonClass();
 var jObject = Newtonsoft.Json.Linq.JObject.Parse(jsonData);
 obj= jObject["Employee"].ToObject<YourJsonClass>();

您的YourJsonClass 将是

 public class YourJsonClass
 
    public string name get; set; 
    public int age  get; set; 
    public string city get; set; 
 

您可以像这样通过obj 访问:

 string name =obj.name;
 int age=obj.age;
 string city=obj.city;

希望对你有帮助。

【讨论】:

这就像我的代码。如果 YourJsonClass 是 Int32、字符串或任何其他 JSON 原语,则会引发异常。【参考方案3】:

您可以使用关键字“动态”而不是硬编码类型,因此它将为您解析类型。 请看这个教程:

tutorial

【讨论】:

问题是解析对象的转换。动态类型不能解决运行时的类转换错误。

以上是关于如何在 C# 中动态转换来自 Json.NET 的解析 JSON 结果?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 json.net 将 c# 通用列表转换为 json?

将 XML 转换为动态 C# 对象

Json.net实现方便的Json转C#(dynamic动态类型)对象

Json.net实现方便的Json转C#(dynamic动态类型)对象

Json.net实现方便的Json转C#(dynamic动态类型)对象

将 json 转换为 C# 数组?