【问题标题】:C# JSON deserialization of array/dictionary数组/字典的 C# JSON 反序列化
【发布时间】:2018-02-01 08:42:24
【问题描述】:

我必须使用 Web 服务 (json)。 我使用 JavaScriptSerializer 建立了序列化/反序列化的通信。

在 99% 的情况下,它都可以正常工作,但是... 错误详细信息是这样返回的:

{"result":"FAIL","error":{"error_code":1,"desc":"INVALID_DATA","details":{"city":["City cannot be blank."]}}}

处理我创建的类:

public class ErrorObj
{
    public int error_code { get; set; }
    public string desc { get; set; }
    public Dictionary<string, string[]> details { get; set; }
}

但是 somtethimes 'details' 是这样返回的:

{"result":"FAIL","error":{"error_code":1,"desc":"ERROR_OPTIONS","details":["Specifying a bank account"]}}

{"result":"FAIL","error":{"error_code":1,"desc":"INVALID_DATA","details":[]}}

要处理这个类应该是这样的:

public class ErrorObj
{
    public int error_code { get; set; }
    public string desc { get; set; }
    public string[] details { get; set; }
}

如何构建对象 (ErrorObj) 来处理所有错误消息?

反序列化代码:

public static T DeSerializeObjectFromJsonString<T>(string jsonString)
{
   T objectOut = default(T);
   Type outType = typeof(T);

   var obj = (T) new JavaScriptSerializer().Deserialize(jsonString, typeof(T));

  return obj;
}

错误信息:

System.InvalidOperationException:类型 'System.Collections.Generic.Dictionary`2[[System.String, mscorlib, 版本=4.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089], 数组的反序列化不支持 [System.String[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'。

【问题讨论】:

    标签: c# json dictionary serialization javascriptserializer


    【解决方案1】:

    你可以像这样使用模型对象。

    public Dictionary&lt;string, string[]&gt; details { get; set; },只需使用 dynamic 而不是 Dictionary&lt;string, string[]&gt;

    因为json字符串detail是不固定的。

    public class Error
    {
        public int error_code { get; set; }
        public string desc { get; set; }
        public dynamic details { get; set; }
    }
    
    public class ErrorObj
    {
        public string result { get; set; }
        public Error error { get; set; }
    }
    

    如果你想知道,你得到了哪个 json?

    您可以使用detail.GetType()。检查类型是否为数组。

    就这么简单

    string DictJson = "{\"result\":\"FAIL\",\"error\":{\"error_code\":1,\"desc\":\"INVALID_DATA\",\"details\":{\"city\":[\"City cannot be blank.\"]}}}";
    
    string ArrayJson = "{\"result\":\"FAIL\",\"error\":{\"error_code\":1,\"desc\":\"ERROR_OPTIONS\",\"details\":[\"Specifying a bank account\"]}}";
    
    ErrorObj errorobj = DeSerializeObjectFromJsonString<ErrorObj>(ArrayJson);
    
    if (errorobj.error.details.GetType().IsArray)
    {
        //receive array detail
    }
    else
    {
        //receive Dictionary<> detail
    }
    

    【讨论】:

    • 但是当我使用 List 时。我无法反序列化:"details":{"city":["City cannot be blank."]}
    • 好的!我修改我的答案。您可以尝试使用dynamic
    • 谢谢。动态类型工作正常。有一些工作可以处理所有可能的返回类型,但它有效:)
    • 我很高兴它可以帮助你:)
    【解决方案2】:

    这很奇怪,因为 web 服务属性不应该在不同的结果中改变它。

    您可以通过更改details 类型来处理它。

    public JToken details { get; set; }
    

    我还建议您坚持 C# 命名约定并为所有属性使用 JsonProperty 属性。

    [JsonProperty("details")]
    public JToken Details { get; set; }
    

    【讨论】:

    • JToken i 来自 JSON.NET 而不是 JavaScriptSerializer?
    猜你喜欢
    • 2019-07-27
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    相关资源
    最近更新 更多