将 JSON 反序列化为匿名对象

76

在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, Culture=neutral, PublicKeyToken=b77a5c561934e089]]”没有无参数的构造函数。

我不确定这个错误的意思。


这正是你要找的:https://dev59.com/RFkR5IYBdhLWcg3w2wt1#70026040 - Ash K
8个回答

53

动态方面怎么样,我想最快的方法是这样的:

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

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

注意:您需要Newtonsoft.json.dll引用


38

JSON.Net是一个在.Net平台下用于处理JSON数据的强大类库。

其中有一个方法DeserializeAnonymousType可以使用。

更新:现在ASP.Net内置了Json.Net,不过我目前最喜欢使用的是JsonFX。它还具有很好的Linq支持,请试用一下。

更新2:我已经转向使用ServiceStack.Text,速度非常快!


有趣,看起来正是OP所寻找的。 - Davy8
1
更新于11月11日,链接现已失效。 - Kieren Johnstone
5
ServiceStack不是免费的!对我来说这很重要。当我达到免费版的限制时,我才发现这一点。 - JDC
ServiceStack自4.0.26版本起现在是免费的,并且它支持将反序列化到通用的JsonObject - thomasb
1
@thomasb 我不知道你在哪里看到的...至少NuGet包的许可证有一个“受限免费使用”条款(版本5.2.0)。 - Marcel Popescu
显示剩余2条评论

16

可以尝试使用DeserializeObject方法,它不需要指定特定的类型。这也解决了一个类似的SO问题。该方法会将反序列化为包含名称/值对的Dictionary<string, object>

更新:为了澄清在这种情况下出现的错误:

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

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


4
这也可以使用内置的JavaScriptSerializer来完成,如下所示:
object result = new JavaScriptSerializer().DeserializeObject(JSONData);

这将返回一个对象数组实例,其中包含键值对。

4
很遗憾,这在 .NET Core 2.1 中并没有。 - Tvde1

2
如果您使用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" }

1
你可以使用 JObject 来反序列化 JSON 字符串:
using Newtonsoft.Json.Linq;

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

1
如果您不想手动提供类型,我发现最简单的方法就是:
var jsonString = JsonHelper.SerializeObject(item);
ExpandoObject obj = JsonHelper.DeserializeObject<ExpandoObject>(jsonString);

1

最近我一直在使用非常棒的JsonFx.Net库,并且我开始欣赏它所做的事情。你可以使用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);

正如您所看到的,您甚至可以为匿名类型指定模板。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接