【发布时间】:2011-09-20 13:28:34
【问题描述】:
我从数据库中读取了一个很长的 json。 我只想要那个 json 的一个属性。
我有两个选择: 一种。为该 json 创建一个接口并反序列化为该接口。 (因为我只需要一个属性,所以这是一种矫枉过正的行为吗?) 湾。找到我需要的子字符串(正则表达式?)
哪个更受欢迎?
更新:我使用的是 .net 3.5
【问题讨论】:
我从数据库中读取了一个很长的 json。 我只想要那个 json 的一个属性。
我有两个选择: 一种。为该 json 创建一个接口并反序列化为该接口。 (因为我只需要一个属性,所以这是一种矫枉过正的行为吗?) 湾。找到我需要的子字符串(正则表达式?)
哪个更受欢迎?
更新:我使用的是 .net 3.5
【问题讨论】:
您为什么不使用JSON.NET 的“LINQ to JSON”方法(@987654322@ 等)进行反序列化,然后通过名称询问您需要的值?
这是足够动态的,因此您无需为所有内容创建接口,但它比使用正则表达式要脆弱得多。
JObject json = JObject.Parse(text);
JToken value = json["foo"]["bar"];
(我相信 JSON.NET 在 .NET 4 中也支持 dynamic,但这里没有特别需要使用它。)
【讨论】:
Regex 必须绝对排除在任何讨论之外。忘记它,就好像它从未存在过一样。
创建和使用强类型是一件好事,也许我会这样做。
但如果你愿意,你也可以使用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。
【讨论】:
在 .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
唯一的缺点是你不能保证对象的确切结构是什么。
上升之处在于,不是通过yourDynamicObject['blah'] 访问成员,而是更像鸭子类型的yourDynamicObject.blah
在 .NET 3.5 上:
您可以使用 Json.NET:http://json.codeplex.com/
【讨论】:
查找子字符串是一个危险的优化。
是否值得优化流程(与 JSON 反序列化相比)并安全地进行此类查找?我们无法回答是,因为它主要取决于上下文。但是我想说NO,因为它显然是在找麻烦:即使它现在可以工作,但将来当你的对象的结构或内容发生变化时,它可能会被破坏。
【讨论】:
旧线程,但这是 .NET 3.5 上的另一种方法:您可以将 DeserializeObject 返回的对象转换为 Dictionary
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
希望对某人有所帮助。
问候
【讨论】:
你可以这样做:
var result = JsonConvert.DeserializeAnonymousType(json, new { Foo="", Bar=""});
这将返回一个包含您定义的字段的动态对象。
【讨论】:
视情况而定。
选项 A 是更严格、更规范、更正式的方式。然而,就像你说的那样,这可能有点矫枉过正。那个json有多胖?从长远来看,选项 A 留下了您可能需要使用多个属性的未来潜在可能性。
选项 B 肯定更加非正式和直接。它今天肯定可以工作,但将来可能需要不同的解决方案。
因此,也许您希望将整个过程包装在一个方法中,以便对调用客户端隐藏实现。返回仅填充了唯一属性的自定义对象。然后,如果将来需要,您可以更改方法以利用全倾斜反序列化。
注意:我认为在 C# 3.5 中反序列化为匿名类型是不可能的。
【讨论】: