我能否在C#中将JSON反序列化为匿名类型?

15

我从数据库读取了一个很长的json字符串,但是我只需要其中的一个属性。

我有两个选择: a. 为该json创建一个接口,并将其反序列化为该接口。(由于我只需要一个属性,这是否有点过度设计?) b. 查找我需要的子字符串(使用正则表达式?)

哪个更好呢?

更新:我正在使用 .net 3.5

7个回答

27
为什么不使用JSON.NET的"LINQ to JSON"方法(JObject等)进行反序列化,然后按名称请求所需的值?这样足够动态,不需要为每个内容创建一个接口,但比使用正则表达式要更加灵活。
JObject json = JObject.Parse(text);
JToken value = json["foo"]["bar"];

我相信JSON.NET在.NET 4中也支持dynamic,但是这里没有特别需要使用它。


18

正则表达式绝对不能参与讨论。就好像它从来不存在一样,请忘掉它。

创建并使用强类型是一个好习惯,也可能是我会采用的方式。

但如果你愿意,也可以使用dynamic

class Program
{
    static void Main()
    {
        var json = "{ 'foo': { 'bar': 'bar value', 'baz': [ 1, 2, 3 ] } }";
        var serializer = new JavaScriptSerializer();
        dynamic value = serializer.DeserializeObject(json);
        Console.WriteLine(value["foo"]["baz"][1]);
    }
}

在控制台上打印2


我正在使用C# 3.5版本。我不认为有动态类型,对吗? - Elad Benda
2
@Elad Benda,没有。那么你可以使用Json.NET,它提供了类似的语法。 - Darin Dimitrov

2

1

你可以做:

var result = JsonConvert.DeserializeAnonymousType(json, new { Foo="", Bar=""});

这将返回一个具有您定义字段的动态对象。

您能否详细阐述一下您的答案,并对您提供的解决方案进行更多描述? - abarisone

1

查找子字符串是一种危险的优化。

与 JSON 反序列化相比,值得优化这个过程吗?进行这样的查找是否安全?我们无法回答“是”,因为它大多取决于上下文。但我感觉应该说“不”,因为这显然会带来麻烦:即使现在可以工作,当您对象的结构或内容发生变化时,它可能会在未来出现问题。


1

虽然这是一个旧的帖子,但是在.NET 3.5中还有另一种方法:您可以将DeserializeObject返回的对象转换为Dictionary<String,Object>。 这与使用.NET 4.0动态关键字的解决方案有些相似:

JavaScriptSerializer serializer = new JavaScriptSerializer();
Object obj = serializer.DeserializeObject("{ 'name': 'vinicius fonseca', 'age': 31 }");
Dictionary<String, Object> ret = (Dictionary<String, Object>)obj;
Console.WriteLine(ret["name"].GetType().Name); // Output: String
Console.WriteLine(ret["name"].ToString()); // Output: vinicius fonseca
Console.WriteLine(ret["age"].GetType().Name); // Output: Int32
Console.WriteLine(ret["age"].ToString()); // Output: 31

希望能对某些人有所帮助。

祝好


0

这要看情况而定。

选项A是更严格、有纪律和正式的方式。但是,就像你所说的,这可能过于繁琐了。那个JSON文件有多大?从长远来看,选项A留下了未来可能需要使用多个属性的潜在可能性。

选项B肯定更不正式和直接了当。它今天肯定有效,但将来可能需要不同的解决方案。

因此,也许您想将整个过程包装在一个方法中,以隐藏调用客户端的实现。返回只填充了单个属性的自定义对象。然后,如果将来需要,您可以更改该方法以利用完全倾斜的反序列化。

注意:我认为在C# 3.5中无法将反序列化为匿名类型。


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