将 JSON 反序列化为匿名对象

Posted

技术标签:

【中文标题】将 JSON 反序列化为匿名对象【英文标题】:Deserialize JSON to anonymous object 【发布时间】:2011-10-17 19:16:55 【问题描述】:

在 C# 中,我已经通过使用这样的代码成功地将匿名对象序列化为 JSON...

var obj = new  Amount = 108, Message = "Hello" ;
javascriptSerializer serializer = new JavaScriptSerializer();
String output = serializer.Serialize(obj);

但是,我希望稍后能够将 JSON 字符串反序列化回匿名对象。像这样的……

var obj2 = serializer.Deserialize(output, object);

但 serializer.Deserialize() 方法需要第二个参数,即反序列化到的对象类型。

我试过这个...

var obj2 = serializer.Deserialize(output, obj.GetType());

但这会产生错误:

没有为 'f__AnonymousType0`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0] 类型定义无参数构造函数。 0.0,文化=中性,PublicKeyToken=b77a5c561934e089]]'。

我不确定这个错误是什么意思。

【问题讨论】:

相关帖子 - Deserialize JSON into C# dynamic object? & Deserializing json to anonymous object in c# 【参考方案1】:

动力学怎么样,我看到的最快的方法是这样的:

dynamic myObject = JsonConvert.DeserializeObject<dynamic>(output);

decimal Amount = Convert.ToDecimal(myObject.Amount);
string Message = myObject.Message;

注意: 您将需要 Newtonsoft.json.dll 参考

【讨论】:

【参考方案2】:

JSON.Net 是一个强大的库,可以在 .Net 中使用 JSON

有一个方法DeserializeAnonymousType你可以点击。

更新:Json.Net 现在包含在 ASP.Net 中,但我最近最喜欢使用的是 JsonFX。它也有很好的 linq 支持,看看吧。

更新 2:我已从 JsonFX 继续,目前使用 ServiceStack.Text,速度很快!

【讨论】:

有趣,看起来正是 OP 想要的。 11 月 11 日更新,链接现已损坏 ServiceStack 不是免费的!对我来说,这很重要。我是在达到免费版的限制时才发现的。 ServiceStack 从 4.0.26 开始免费,并且支持反序列化为通用 JsonObjects @thomasb 我不知道你在哪里看到... NuGet 包的许可证至少有一个“限制免费使用”条款(版本 5.2.0)。跨度> 【参考方案3】:

使用the DeserializeObject method 怎么样,它不需要特定类型。这也解决了a similar SO question。该方法反序列化为包含名称/值对的Dictionary&lt;string, object&gt;

更新:澄清您在执行此操作时遇到的错误:

var obj2 = serializer.Deserialize(output, obj.GetType());

给定obj 的类型,Deserialize 将尝试使用默认构造函数创建该类型的新实例。 C# 中的匿名类型没有公共的无参数构造函数,因此操作失败。

【讨论】:

【参考方案4】:

这也可以使用内置的 JavaScriptSerializer 来完成,如下:

object result = new JavaScriptSerializer().DeserializeObject(JSONData);

这将返回一个带有键值对的 object[] 实例。

【讨论】:

不幸的是,这不在 .net core 2.1 中。【参考方案5】:

最近我一直在使用很棒的JsonFx.Net library,我开始欣赏它的作用。您可以使用 Nuget 包管理器在 Visual Studio 中直接安装它。

代码是这样的,

var reader = new JsonReader();
string input = @" ""first"": ""Foo"", ""last"": ""Bar"" ";
var template = new  first=String.Empty, middle=String.Empty, last=String.Empty ;
var output = reader.Read(input, template);

如您所见,您甚至可以为匿名类型指定模板。

【讨论】:

【参考方案6】:

您可以使用NewtonSoft.Json 的DeserializeAnonymousType 方法来做到这一点。

以下示例甚至可以将 JSON 反序列化为匿名对象的列表。使用您希望它反序列化到的任何定义。

var json = System.IO.File.ReadAllText(@"C:\TestJSONFiles\yourJSONFile.json");
var fooDefinition = new  a = "", b = 0 ; // type with fields of string, int
var fooListDefinition = Enumerable.Range(0, 0).Select(e => fooDefinition).ToList();

var foos = JsonConvert.DeserializeAnonymousType(json, fooListDefinition);

【讨论】:

【参考方案7】:

您可以使用 JObject 来反序列化 JSON 字符串:

using Newtonsoft.Json.Linq;

string output = "\"Amount\" = 108, \"Message\" = \"Hello\"";
var amount = JObject.Parse(output)["Amount"];

【讨论】:

【参考方案8】:

如果你使用 Newtonsoft.Json,你可以尝试 DeserializeAnonymousType 方法

    var obj1 = new  Amount = 108, Message = "Hello" ;
    var json=JsonConvert.SerializeObject(obj1);

    // or as well
    var json= " \"Amount\" : 108, \"Message\" : \"Hello\" ";
   
   //Deserialization

   var definition = new  Amount = 0, Message = "" ;

    //obj2 type is "anonymous"
   var obj2 = JsonConvert.DeserializeAnonymousType(json,definition); 

结果

 Amount = 108, Message = "Hello" 

【讨论】:

以上是关于将 JSON 反序列化为匿名对象的主要内容,如果未能解决你的问题,请参考以下文章

json字符串反序列化成匿名类型对象

如何解析JSON.NET中的匿名数组?

如何将 C# 匿名类型序列化为 JSON 字符串?

通过 Web 传输实体框架对象并通过 JSON 返回的最佳方式

Jackson序列化(8)— 支持泛型的反序列化

我可以将匿名类型序列化为 xml 吗?