简体   繁体   English

C#反序列化动态JSON

[英]C# deserialize dynamic JSON

I have the following Json string that I need to deserialize. 我有以下需要反序列化的Json字符串。

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

The first field "123456789" is an id number, so basically this value can be different depending on the data being queried. 第一个字段“123456789”是一个id号,所以基本上这个值可能会有所不同,具体取决于被查询的数据。

I'm using C# in visual studio. 我在visual studio中使用C#。 Obviously because the value of the first field can change I can't use a predefined class to deserialize the JSON into because this field will be used as the class name but the field value won't match the class name. 显然因为第一个字段的值可以更改,所以我不能使用预定义的类来反序列化JSON,因为该字段将用作类名,但字段值与类名不匹配。

Is there a way to deserialize this into some sort of dynamic class but still access the fields as if it was a predefined class? 有没有办法将其反序列化为某种动态类但仍然访问字段,就好像它是一个预定义的类?

Alternatively is there a way to deserialize this into a predefined class even thought the class name doesn't match? 或者有没有办法将其反序列化为预定义的类,即使类名不匹配?

The service providing this data is a third party one so i don't have any control over it. 提供此数据的服务是第三方服务,因此我无法控制它。

Here is one way which I use in production code. 这是我在生产代码中使用的一种方法。 It might not be perfect, but it gets the job done. 它可能不完美,但它完成了工作。

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....
        }            
    }

The object you receive back will be a generic Map, List, or whatever depending on the structure of the JSON. 您收到的对象将是一个通用的Map,List或其他任何内容,具体取决于JSON的结构。 If you know what structure to expect, this is very useful without writing a customized parser or target object type. 如果您知道期望的结构,那么在不编写自定义解析器或目标对象类型的情况下,这非常有用。

You could then enumerate the keys of the Map, for example, to find your key that varies. 然后,您可以枚举Map的键,例如,找到变化的键。 A wrapper or conversion would then provide a consistent API to the rest of your application layer. 然后,包装器或转换将为应用程序层的其余部分提供一致的API。 Something like: 就像是:

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;
     }
}

I liked answer above so I refactored it a bit. 我喜欢上面的答案,所以我重新调整了一下。 You'll need references to System.Web.Extensions.dll and System.Web.Script.Serialization . 您需要引用System.Web.Extensions.dllSystem.Web.Script.Serialization

Here's the class: 这是班级:

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()
        };
    }
}

And how to call it: 以及如何称呼它:

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

You'll need to implement error handling on your own however. 但是,您需要自己实现错误处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM