3

我有以下需要反序列化的 Json 字符串。

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

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

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

有没有办法将其反序列化为某种动态类,但仍像访问预定义类一样访问字段?

或者,即使类名不匹配,是否有办法将其反序列化为预定义类?

提供此数据的服务是第三方服务,因此我无法控制它。

4

2 回答 2

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

您收到的对象将是通用 Map、List 或其他任何取决于 JSON 结构的对象。如果您知道预期的结构,这将非常有用,无需编写自定义解析器或目标对象类型。

然后,您可以枚举 Map 的键,例如,查找您的变化的键。然后,包装器或转换将为应用程序层的其余部分提供一致的 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;
     }
}
于 2012-11-22T02:08:39.653 回答
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);

但是,您需要自己实现错误处理。

于 2012-11-22T02:42:35.173 回答