我可以在j#中将json反序列化为匿名类型吗?

时间:2011-09-20 13:28:35

标签: c# regex json .net-3.5

我从DB读了一个长json。 我只想要那个json的一个属性。

我有两个选择: 一个。为该json创建一个接口并反序列化到该接口。    (因为我只需要一个属性,这是一种矫枉过正吗?) 湾找到我需要的子串(正则表达式?)

哪一个更受欢迎?

更新:我正在使用.net 3.5

7 个答案:

答案 0 :(得分:26)

为什么不使用JSON.NET的“LINQ to JSON”方法(JObject等)进行反序列化,只是按名称询问所需的值?

这是足够动态的,所以你不需要为所有创建一个接口,但它比使用正则表达式要脆弱得多。

JObject json = JObject.Parse(text);
JToken value = json["foo"]["bar"];

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

答案 1 :(得分: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

答案 2 :(得分:2)

在.NET 4上:

你可以通过使用此处描述的C#4.0的dynamic功能,做一些类似于你想要的东西减去正则表达式的需要(你不应该使用正则表达式来做这样的事情!):{{3 }}

唯一的缺点是你不能保证对象的确切结构是什么。

上升是指不是通过yourDynamicObject['blah']访问成员,而是更多鸭子类型yourDynamicObject.blah

在.NET 3.5上:

您可以使用Json.NET:http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx

答案 3 :(得分:1)

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

是否值得优化流程(与JSON反序列化相比)并且可以安全地进行此类查找?我们无法回答,因为它主要依赖于上下文。但是我想说 NO ,因为它显然在寻找麻烦:即使它现在有效,但是当对象的结构或内容发生变化时,它可能会在未来被破坏。

答案 4 :(得分: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

希望它有所帮助。

此致

答案 5 :(得分:0)

取决于。

选项A是更严格,更严格,更正式的方式。然而,再次像你说的那样可能有点矫枉过正。这个json有多胖?从长远来看,选项A留下了未来可能需要使用多个财产的可能性。

选项B绝对是非正式和直接的。它今天肯定会有用,但将来可能需要一个不同的解决方案。

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

注意:我不认为在C#3.5中对匿名类型进行反序列化是可能的。

答案 6 :(得分:0)

你可以这样做:

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

这将返回一个动态对象,其中包含您定义的字段。