繁体   English   中英

使用 Newtonsoft Json.Net 反序列化字符串化(引号括起来)嵌套对象

[英]Deserializing stringified (quote enclosed) nested objects with Newtonsoft Json.Net

使用 Jackson 反序列化字符串化(引号括起来)嵌套对象相同的问题,但针对 C# 和 Newtonsoft Json.Net。 问题是如何使用 Json.Net 反序列化 JSON 的嵌套字符串表示。 来自 REST 端点的示例响应:

{
    "Id": "abcd1234",
    "Foo": "{\"field1\": "abc", \"field2\": \"def\"}"
}

C# 模型:

public class Model {
    public Guid Id { get; set; }
    public Dictionary<string, string> Foo { get; set; }
}

仅调用JsonConvert.DeserializeObject<Model>(returnedJson)就会出错,因为其返回形式的 Foo 是字符串化的 JSON,也就是一个字符串。 我们的 JSON 响应中的其他字段也是这种情况,这些字段在其模型中关联了不同的 Dictionary 类型(例如 Dictionary<string, int> 和 Dictionary<string, DateTime>)。

处理这个问题的最简单方法是什么? 是否需要自定义 JsonConverter 或者是否有一些内置方法来处理它?

JsonConverter 可能是处理这种隐式转换的最简单方法。 这是一种适用于您的情况。

public class MyConverter: JsonConverter
{
  public override bool CanConvert(Type objectType)
  {
    return objectType == typeof(string);
  }

  public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  {
    return JsonConvert.DeserializeObject(reader.Value as string, objectType);
  }

  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  {
    throw new NotImplementedException();
  }
}

然后你用这样的属性装饰该属性:

public class Model
{
  public string Id { get; set; }
  [JsonConverter(typeof(MyConverter))]
  public Dictionary<string, string> Foo { get; set; }
}

为了跟进,我使用了与@VijayeR 推荐的非常相似的解决方案,但需要稍微调整一下,因为它仍然给我带来了一些问题。 一个问题是,当使用装饰器时,显然 CanConvert 根本不会被调用,因为 Json.Net 假设您已将正确的转换器分配给该属性。 这对我有用:

public class NestedJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jToken = JToken.Load(reader);

        if (jToken.Type == JTokenType.String)
        {
            jToken = JToken.Parse((string) jToken);
        }

        return jToken.ToObject(objectType);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanWrite => false;
}

暂无
暂无

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

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