简体   繁体   中英

JSON deserialization throws exception when nested object is empty

Hello I have a problem with deserializing JSON to object.

I have this kind of JSON:

{
"my_obj":{
    "id":"test",
    "nested_obj":{
        "value":"testValue",
        "desc":"testDesc"}
    }
}

But sometimes I receive empty nested_obj:

{
"my_obj":{
    "id":"test",
    "nested_obj":""
    }
}

My code to handle this:

public class MyObj
{
    public string id { get; set; }
    public NestedObj nested_obj { get; set; }
}

public class NestedObj
{
    public string value { get; set; }
    public string desc { get; set; }
}

public virtual T Execute<T>(IRestRequest request) where T : new()
{
    request.RequestFormat = DataFormat.Json;
    var response = _client.Execute<T>(request);

    LogResponse(response);
    CheckResponseException(response);

    return response.Data;
}

When the nested_obj is not empty, then deserialization works perfectly fine. But when nested_obj is empty, I receive this exception:

Unable to cast object of type 'System.String' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.

Is it possible to deserialize it this way? Unfortunately it is not possible to change response of the WebService, so i should parse it correctly in my app.

Simply use Newtonsoft's Json.NET . It works fine. Here's a short snippet from LINQPad:

void Main()
{
    JsonConvert.DeserializeObject<A>(@"{
        property: ""apweiojfwoeif"",
        nested: {
            prop1: ""wpeifwjefoiwj"",
            prop2: ""9ghps89e4aupw3r""
        }
    }").Dump();
    JsonConvert.DeserializeObject<A>(@"{
        property: ""apweiojfwoeif"",
        nested: """"
    }").Dump();
}

// Define other methods and classes here
class A {
    public string Property {get;set;}
    public B Nested {get;set;}
}

class B {
    public string Prop1 {get;set;}
    public string Prop2 {get;set;}
}

And the result is

结果

Ouch. That has nothing to do with your code as you already know. It's just that the web service is sometimes defining nested_obj as a NestedObj object, and sometimes as a string (when it sends null). So your parser doesn't know what to make of it.

Your best bet might be to write a custom parser for it. (which makes sense since it's not standard JSON due to the type morphing).

There's a section on writing a custom parser for RestSharp here

They tell you to implement IDeserializer but I'd suggest you simply extend JsonDeserializer to add your special custom functionality and delegate back to the super class for everything else.

Reason is because in

{
"my_obj":{
    "id":"test",
    "nested_obj":{
        "value":"testValue",
        "desc":"testDesc"}
    }
}

nested object is receiving an object type

while in

{
"my_obj":{
    "id":"test",
    "nested_obj":""
    }
}

it is receiving string type.

if

it returns

{
"my_obj":{
    "id":"test",
    "nested_obj":null
    }
}

then it will be able to parse successfully.

try using http://json2csharp.com/ to convert both of your json and see the difference

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