2012-11-22 66 views
3

我有我需要反序列化的以下Json字符串。C#反序列化动态JSON

{"123456789": 
    {"short_description":"Delivered", 
    "detail_description":"Your item has been delivered" 
    } 
} 

第一个字段“123456789”是一个id号,所以基本上这个值可以根据查询的数据而不同。

我使用C#在Visual Studio中。很显然,因为第一个字段的值可能会改变,所以我不能使用预定义的类来反序列化JSON,因为这个字段将用作类名,但是字段值不会与类名相匹配。

有没有办法来反序列化到某种动态类的这一点,但仍然可以访问域,如果它是一个预定义的班?

或者是有没有办法来反序列化为预定义的类这甚至想到了类名称不匹配?

服务提供这个数据是第三方之一,所以我没有对任何控制。

+0

[将反序列化JSON转换为C#动态对象?](http://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object) – jbtule

+0

检查http:// www。 newtonsoft.com/json/help/html/deserializeobject.htm – KingRider

回答

5

下面是我在生产代码中使用的一种方式。它可能不完美,但它完成了工作。

using using System.Web.Script.Serialization; 

// ..... 

    public object GetJson(string url) 
    { 
     var json = Get(url); // I have code that makes this work, it gets a JSON string 

     try 
     { 
      var deserializer = new JavaScriptSerializer(); 
      var result = deserializer.DeserializeObject(json); 

      return result; 
     } 
     catch (ArgumentException e) 
     { 
      // Error handling.... 
     }    
    } 

您收到返回的对象将是一个通用的地图,列表,或任何因JSON的结构。如果您知道期望的结构,那么在编写定制解析器或目标对象类型的情况下,这非常有用。

然后,您可以枚举该地图的键,例如,找到你的密钥变化。包装器或转换将为应用程序层的其余部分提供一致的API。喜欢的东西:

public class Order { 
    public string OrderNum { private set; get; } 
    public string ShortDesc { private set; get; } 
    public string Desc { private set; get; } 

    public static Order FromJson(object jsonResult) 
    { 
      var m = jsonResult as Map<string, object>; 

      // Handle errors, but I am not 

      var firstPair = m.First(); 

      var detail = firstPair.Value as Map<string, object>; 

      var dummy = new Order() 
      { 
       OrderNum = firstPair.Key, 
       ShortDesc = detail["short_description"].ToString(); 
       Desc = detail["detail_description"].ToString(); 
      } 

      return dummy; 
    } 
} 
3

我喜欢上面的答案,所以我重构它一下。您需要参考System.Web.Extensions.dllSystem.Web.Script.Serialization

这里的类:

public class Order 
{ 
    public string OrderNum { private set; get; } 
    public string ShortDesc { private set; get; } 
    public string Desc { private set; get; } 

    public static Order FromJson(string jsonResult) 
    { 
     JavaScriptSerializer js = new JavaScriptSerializer(); 
     // Should deserialize right to Dictionary<string, object> 
     // var result = ((Dictionary<string, object>)js.Deserialize<dynamic>(jsonResult)).First(); 
     var result = js.Deserialize<Dictionary<string, object>>(jsonResult).First(); 
     var detail = (Dictionary<string, object>)result.Value; 

     return new Order() 
     { 
      OrderNum = result.Key, 
      ShortDesc = detail["short_description"].ToString(), 
      Desc = detail["detail_description"].ToString() 
     }; 
    } 
} 

以及如何调用它:

string json = "{\"123456789\": {\"short_description\":\"Delivered\", \"detail_description\":\"Your item has been delivered\" } }"; 
Order o = Order.FromJson(json); 

你需要执行错误处理你自己不过。

+0

酷.... :-)生产代码需要更多的错误处理,但:-)我喜欢动态的技巧。我不确定C#在我开始使用这种方法或其祖先时是否具有动态性,并且我从未更新过我的技术。 – SAJ14SAJ

+0

只要想一想,在这个例子中你甚至不需要动态的,你可以反序列化'Dictionary '(我提供了一个编辑)。如果Json格式正确,那么'动态'返回会在没有所有'Key' /'Value'调用的情况下工作。 –

+0

这是有道理的....我的代码片段是通用的,这就是为什么我反序列化为对象。正如你所说的,我的技术是基于我实际做的,而不是针对一个特定的案例进行优化。有时我会得到地图列表,有时候会列出地图,有时甚至只是字符串或其他。这是我的ETL库的一部分,用于从HTTP/HTML/JSON源(通常是Domino数据库,但您明白)提取。有一个Xml等价物,和更多的包装,但他们没有出现:-) – SAJ14SAJ