如何解释和反序列化此JSON响应 [英] How to interpret and deserialize this JSON response

查看:101
本文介绍了如何解释和反序列化此JSON响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题源自另一个主题,可以在以下位置找到: 从JSON数组中提取对象到列表

This question originates from another topic which can be found at: Extract objects from JSON array to list

问题是我收到以下JSON响应,而我的JSON.NET反序列化器不理解它,但是还有其他几个JSON验证器,例如

The thing is that I'm receiving the following JSON response, and my JSON.NET deserializer doesn't understand it, but several other JSON validators like https://jsonlint.com say that it is valid.

[
{"value":"{\"code\":\"MO\",\"description\":\"Monday\",\"isSet\":false}","nr":1}
,{"value":"{\"code\":\"TU\",\"description\":\"Tuesday\",\"isSet\":true}","nr":2}
]

在我看来,这里的问题是值对象看起来像JSON对象,但实际上是一个字符串. JsonConvert.DeserializeObject一直引发错误,直到我删除了额外的引号()并转义了字符.

In my opinion the problem here is that the value object looks like a JSON object, but actually is a string. JsonConvert.DeserializeObject keeps throwing errors until I remove the additional quotes (") and escaping chars.

问题是,为什么此响应的格式是这样的?以及如何告诉解串器如何使用它呢?我敢肯定,删除或替换字符不是要走的路.

So the question is, why is this response formatted like this? And how to tell the deserializer how to work with it? I'm sure that removing or replacing chars isn't the way to go.

这是我在做什么:

public class Value
{
    public string code { get; set; }
    public string description { get; set; }
    public bool isSet { get; set; }
}

public class RootObject
{
    public Value value { get; set; }
    public int nr { get; set; }
}

var json = JsonConvert.DeserializeObject<List<RootObject>>(serviceResult);

以上操作无效.

目前,我已经通过这种方式解决了这个问题.但是我一直认为上面的内容加上反序列化器会更优雅.

For the time being I have solved the issue this way. But I keep thinking that the above, with the deserializer, is more elegant.

JArray jArray = JArray.Parse(serviceResult);
List<Value> values = jArray.Select(x => JObject.Parse(x["value"].ToString()).ToObject<Value>()).ToList();

推荐答案

最简单的方法是使用自定义JsonConverter,例如这样的东西:

The easiest way to do this would be to use a custom JsonConverter, for example something like this:

public class StringToObjectConverter<T> : Newtonsoft.Json.JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, 
        JsonSerializer serializer)
    {
        //This will only be needed if you also need to serlialise
        writer.WriteRaw(JsonConvert.SerializeObject(value));
    }

    public override object ReadJson(JsonReader reader, Type objectType, 
        object existingValue, JsonSerializer serializer)
    {
        return JsonConvert.DeserializeObject<T>(reader.Value.ToString());
    }

    public override bool CanRead => true;
    //We can only work with the type T, you could expand this to cope with derived types
    public override bool CanConvert(Type objectType) => typeof(T) == objectType;
}

现在使用这些模型,尤其要注意Value属性上的属性:

Now using these models, noting in particular the attribute on the Value property:

public class RootObject
{
    [JsonConverter(typeof(StringToObjectConverter<Value>))]
    public Value value { get; set; }
    public int nr { get; set; }
}

public class Value
{
    public string code { get; set; }
    public string description { get; set; }
    public bool isSet { get; set; }
}

现在这是一个简单的反序列化:

Now it's a simple deserialisation:

var json = "....";
var rootObjects = JsonConvert.DeserializeObject<List<RootObject>>(json);

这篇关于如何解释和反序列化此JSON响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆