简体   繁体   中英

C# JSON deserialization of array/dictionary

I must consome web service (json). I build a communication with serialization / deserialization with JavaScriptSerializer.

In 99% its works fine, but... Error details is returned like that:

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

To handle that i created Class:

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

But somtethimes 'details' is returned like that:

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

or

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

To handle thi the class should be like that:

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

How to build object ( ErrorObj ) to handle all error messages?

Deserialization code:

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

Error message:

System.InvalidOperationException : Type 'System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], [System.String[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' is not supported for deserialization of an array.

You may use model object like this.

The public Dictionary<string, string[]> details { get; set; } public Dictionary<string, string[]> details { get; set; } public Dictionary<string, string[]> details { get; set; } , Just use dynamic rather than Dictionary<string, string[]> .

Because the json string detail is unfixed.

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

If you want to know,which json did you get?

You can use detail.GetType() . To check the type is or isn't array.

like this simple

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
}

This is fairly weird, because a webservice property should not change it type in different results.

You can handle it, by changing details type.

public JToken details { get; set; }

I would also suggest you to stick to C# naming convention and use JsonProperty attribute, for all properties.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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