2011-09-20 40 views
15

我从DB读取了一个长json。 我只想要那个json的一个属性。我可以反序列化JSON到匿名类型的C#?

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

哪一个是首选?

更新:我使用.NET 3.5

回答

26

你为什么不反序列化使用JSON.NET的‘LINQ到JSON’的方式(JObject等),只要求你需要通过名称值?

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

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

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

2

在.NET 4:

可以种做些什么像你想减去需要什么样的正则表达式(和你不应该使用正则表达式是这样的!)通过这里所描述的C#4.0的dynamic功能:http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx

唯一的缺点是,你不能保证什么e对象的xact结构是。

上去是不是通过yourDynamicObject['blah']访问的成员,这是更鸭型杂交yourDynamicObject.blah

在.NET 3.5:

您可以使用Json.NET:http://json.codeplex.com/

18

正则表达式必须绝对没有任何讨论。忘记它,就好像它从来没有存在过。

创建和使用强类型是一件好事,也许我会走的路。在控制台上

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

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

+0

我使用C#3.5我不认为有动态类型。对 ? –

+2

@Elad Benda,没有。那么你可以使用[Json.NET](http://json.codeplex.com/),它提供了类似的语法。 –

0

这取决于。

选项A是更严格,严谨和正式的方式。然而,就像你说的那样,这可能是过度的。 json有多胖?长期来看,期权A会留下未来潜在的可能性,您可能需要使用多个房产。

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

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

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

1

查找子串是一个危险的优化。

是否值得优化过程(与JSON反序列化相比)并且安全地进行这样的查找?我们不能回答是的,因为它主要依赖于上下文。但我觉得自己说的是NO,因为它显然在寻找麻烦:即使它现在有效,将来当你的结构或内容发生变化时,它可能会被打破。

1

旧的线程,但这里有另一种方法在.NET 3.5上:您可以将由DeserializeObject返回的对象转换为字典<字符串,对象>。它与使用.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

你可以这样做:

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

这将返回一个动态对象与你定义的字段。

+0

您能否详细说明您的答案,并添加关于您提供的解决方案的更多描述? – abarisone