将 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 开始免费,并且支持反序列化为通用JsonObject
s
@thomasb 我不知道你在哪里看到... NuGet 包的许可证至少有一个“限制免费使用”条款(版本 5.2.0)。跨度>
【参考方案3】:
使用the DeserializeObject method 怎么样,它不需要特定类型。这也解决了a similar SO question。该方法反序列化为包含名称/值对的Dictionary<string, object>
。
更新:澄清您在执行此操作时遇到的错误:
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 反序列化为匿名对象的主要内容,如果未能解决你的问题,请参考以下文章