简体   繁体   English

当嵌套对象为空时,JSON反序列化将引发异常

[英]JSON deserialization throws exception when nested object is empty

Hello I have a problem with deserializing JSON to object. 您好,我在将JSON反序列化为对象时遇到问题。

I have this kind of JSON: 我有这种JSON:

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

But sometimes I receive empty nested_obj: 但有时我会收到空​​的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. 当nested_obj不为空时,反序列化可以很好地工作。 But when nested_obj is empty, I receive this exception: 但是,当nested_obj为空时,我收到此异常:

Unable to cast object of type 'System.String' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'. 无法将类型为“ System.String”的对象转换为类型为“ 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. 不幸的是,不可能更改WebService的响应,因此我应该在我的应用程序中正确解析它。

Simply use Newtonsoft's Json.NET . 只需使用Newtonsoft的Json.NET即可 It works fine. 工作正常。 Here's a short snippet from LINQPad: 这是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). 只是Web服务有时将nested_obj定义为NestedObj对象,有时定义为字符串(当它发送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). (这很有意义,因为由于类型变形,它不是标准的JSON)。

There's a section on writing a custom parser for RestSharp here 有一个关于编写自定义解析器RestSharp节在这里

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. 他们告诉您实现IDeserializer但我建议您仅扩展JsonDeserializer即可添加特殊的自定义功能,然后将其委托给超类。

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 尝试使用http://json2csharp.com/转换两个json并查看其中的区别

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

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