Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用JSON.net将JSON对象反序列化为动态对象_C#_.net_Json.net - Fatal编程技术网

C# 使用JSON.net将JSON对象反序列化为动态对象

C# 使用JSON.net将JSON对象反序列化为动态对象,c#,.net,json.net,C#,.net,Json.net,是否可以使用json.net从json反序列化返回动态对象?我想这样做: dynamic jsonResponse = JsonConvert.Deserialize(json); Console.WriteLine(jsonResponse.message); 注意:在我2010年回答这个问题时,如果没有某种类型,就无法进行反序列化,这允许您在不定义实际类的情况下进行反序列化,并允许使用匿名类进行反序列化 您需要有某种类型来反序列化。您可以按照以下思路做一些事情: var product

是否可以使用json.net从json反序列化返回动态对象?我想这样做:

dynamic jsonResponse = JsonConvert.Deserialize(json);
Console.WriteLine(jsonResponse.message);

注意:在我2010年回答这个问题时,如果没有某种类型,就无法进行反序列化,这允许您在不定义实际类的情况下进行反序列化,并允许使用匿名类进行反序列化


您需要有某种类型来反序列化。您可以按照以下思路做一些事情:

var product = new { Name = "", Price = 0 };
dynamic jsonResponse = JsonConvert.Deserialize(json, product.GetType());
我的答案基于.NET4.0内置JSON序列化程序的解决方案。此处有反序列化到匿名类型的链接:


我知道这是一篇老文章,但JsonConvert实际上有一个不同的方法,所以应该是

var product = new { Name = "", Price = 0 };
var jsonResponse = JsonConvert.DeserializeAnonymousType(json, product);

Json.NET允许我们这样做:

dynamic d = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}");

Console.WriteLine(d.number);
Console.WriteLine(d.str);
Console.WriteLine(d.array.Count);
输出:

 1000
 string
 6
此处的文档:


另请参见和

自Json.NET 4.0发行版1起,有本机动态支持:

[Test]
public void DynamicDeserialization()
{
    dynamic jsonResponse = JsonConvert.DeserializeObject("{\"message\":\"Hi\"}");
    jsonResponse.Works = true;
    Console.WriteLine(jsonResponse.message); // Hi
    Console.WriteLine(jsonResponse.Works); // True
    Console.WriteLine(JsonConvert.SerializeObject(jsonResponse)); // {"message":"Hi","Works":true}
    Assert.That(jsonResponse, Is.InstanceOf<dynamic>());
    Assert.That(jsonResponse, Is.TypeOf<JObject>());
}
[测试]
公共空间动态序列化()
{
动态jsonResponse=JsonConvert.DeserializeObject(“{\”消息\“:\”嗨\“}”);
jsonResponse.Works=true;
Console.WriteLine(jsonResponse.message);//嗨
Console.WriteLine(jsonResponse.Works);//True
Console.WriteLine(JsonConvert.SerializeObject(jsonResponse));//{“message”:“Hi”,“Works”:true}
Assert.That(jsonResponse,Is.InstanceOf());
Assert.That(jsonResponse,Is.TypeOf());
}
当然,获取当前版本的最佳方式是通过NuGet

更新(2014年12月11日)以回应评论:

这个很好用。如果在调试器中检查该类型,您将看到该值实际上是动态的。基础类型是
JObject
。如果要控制类型(如指定
ExpandoObject
),请执行此操作


是的,您可以使用JsonConvert.DeserializeObject来执行此操作。要执行此操作,只需执行以下简单操作:

dynamic jsonResponse = JsonConvert.DeserializeObject(json);
Console.WriteLine(jsonResponse["message"]);

如果你只是反序列化为dynamic,你会得到一个JObject。你可以通过使用ExpandoObject得到你想要的

var converter = new ExpandoObjectConverter();    
dynamic message = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);
var converter=新的ExpandoObjectConverter();
动态消息=JsonConvert.DeserializeObject(jsonString,converter);

如果您将JSON.NET与没有JObject的旧版本一起使用

这是从JSON生成动态对象的另一种简单方法:

NuGet安装

PM> Install-Package JDynamic
支持使用字符串索引访问成员,如:

dynamic json = new JDynamic("{a:{a:1}}");
Assert.AreEqual(1, json["a"]["a"]);
测试用例

您可以按如下方式使用此util:

直接获取值

dynamic json = new JDynamic("1");

//json.Value
2.获取json对象中的成员

dynamic json = new JDynamic("{a:'abc'}");
//json.a is a string "abc"

dynamic json = new JDynamic("{a:3.1416}");
//json.a is 3.1416m

dynamic json = new JDynamic("{a:1}");
//json.a is integer: 1
3.可数

dynamic json = new JDynamic("[1,2,3]");
/json.Length/json.Count is 3
//And you can use json[0]/ json[2] to get the elements

dynamic json = new JDynamic("{a:[1,2,3]}");
//json.a.Length /json.a.Count is 3.
//And you can use  json.a[0]/ json.a[2] to get the elements

dynamic json = new JDynamic("[{b:1},{c:1}]");
//json.Length/json.Count is 2.
//And you can use the  json[0].b/json[1].c to get the num.
其他


是的,这是可能的。我一直在这么做

dynamic Obj = JsonConvert.DeserializeObject(<your json string>);
dynamic Obj=JsonConvert.DeserializeObject();
对于非本机类型来说有点棘手。假设在您的Obj中有一个ClassA和ClassB对象。它们都转换为JObject。您需要做的是:

ClassA ObjA = Obj.ObjA.ToObject<ClassA>();
ClassB ObjB = Obj.ObjB.ToObject<ClassB>();
ClassA ObjA=Obj.ObjA.ToObject();
ClassB ObjB=Obj.ObjB.ToObject();


这将把json负载反序列化为匿名类型,而不是动态类型。匿名类型和动态类型是不同的,我认为这不能解决问题。是否需要使用两个变量?为什么不在第二个语句中重用第一个变量?请注意,对于数组,语法是
JArray.Parse。为什么我们需要使用动态单词?我害怕以前从未使用过:在VB.Net中,你需要做
Dim d As Object=JObject.Parse(“{number:1000,str:'string',array:[1,2,3,4,5,6]}”)
@MonsterMMORPG你应该:)动态在几乎所有情况下都是一种反模式,但是,时不时,您可能会遇到使用它是合理的情况:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException发生HResult=-2146233088 Message='Newtonsoft.Json.Linq.JObject'不包含'number'源=Microsoft.CSharp StackTrace:在Microsoft.CSharp.RuntimeBinder.RuntimeBinderController.submitror(CError peror)的定义这似乎永远不会起作用。它只返回一个JObject,而不是一个动态变量。顺便说一句,这是有效的:JsonConvert.DeserializeObject(STRING);通过适当的反序列化,因此我们没有JObject等@Gutek不确定您的问题是什么。你运行代码了吗?我在测试中添加了断言,并添加了一个不在原始json中的属性。包含调试器的屏幕截图。@DavidPeden如果您有JObject,并尝试在Razor中绑定它,则会出现异常。问题是关于反序列化到动态对象-JObject是动态的,但包含像JValue这样的“自有”类型,而不是基元类型。如果返回类型是JValue,我不能在Razor中使用
@Model.Prop
名称。这是可行的,但每个动态属性都是
JValue
。这让我很困惑,因为我在调试器/即时窗口中工作,没有看到的只是
string
s。David在下面的屏幕截图中显示了这一点。
JValue
是可转换的,因此您可以只执行
string m=jsonResponse。message
JsonConvert
不包含名为
反序列化
的方法。它应该是反序列化对象,但这应该是可以接受的答案。这是有效的:D非常感谢您,所有其他答案对我都不起作用。我试图使用DeserializeObject,但是没有使用jsonResponse[“message”],而是使用我通常用于常规类对象的语法:jsonResponse.message我支持你phill不知道为什么人们会投票反对,如果有人可以的话。。请解释为什么?他们投了反对票,因为问题是关于不带类型的反序列化。答案在2010年撰写时是有效的,当时没有其他解决方案。在JSON.NET提供支持之前的一小段时间内,这甚至是公认的答案。这不会生成动态对象。这将生成一个JObject,您将其作为动态对象引用。但它仍然是内部的作业对象。@ghostbust555所以,与
dynamic d没有什么不同=
ClassA ObjA = Obj.ObjA.ToObject<ClassA>();
ClassB ObjB = Obj.ObjB.ToObject<ClassB>();