首页 > 解决方案 > 如何在不添加属性的情况下自定义 Json.net 中嵌套属性的反序列化

问题描述

假设我有这些课程:

public class Bar
{
    public Foo MyFoo { get; set; }
}

public class Foo
{
    public string[] Stuff { get; set; }
}

我有这个 JSON 结构:

{
  "MyFoo":
  {
    "Stuff":"those,are,my,stuff"
  }
}

我有一个代码路径,其中 aJObject正在转换为Bar使用如下代码:

myJObject.ToObject(typeof(Bar))

现在我需要做的是提供ToObject一个自定义序列化程序,将字符串属性转换为字符串Stuff数组(使用string.Split(...).ToArray()

我被要求不要在客户端类“Bar”上添加属性,所以在环顾四周后,它似乎ContractResolver是有序的,但问题是解析器只允许我处理根类型的直接属性,即Bar在我的示例中,并且我无法JsonConverter在嵌套属性上注册 a。

所以我对你们的问题是,这甚至可以使用 Json.net 实现吗?

标签: c#json.netjson-deserialization

解决方案


根据您的描述,我不明白您为什么需要ContractResolver. 您知道要特别反序列化的属性将始终是 type string[],因此只需制作一个处理该类型的转换器。也许是这样的:

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

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

        if (token.Type == JTokenType.Null) 
            return null;

        if (token.Type == JTokenType.String)
            return ((string)token).Split(',');

        if (token.Type == JTokenType.Array) 
            return token.ToObject<string[]>(serializer);

        throw new JsonException("Unexpected token type: " + token.Type);
    }

    public override bool CanWrite => false;

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

然后,要将它与您的JObject.JsonSerializerToObject()

var serializer = new JsonSerializer();
serializer.Converters.Add(new CsvStringConverter());

var bar = myJObject.ToObject<Bar>(serializer);

在这里工作演示:https ://dotnetfiddle.net/qmeBoh


推荐阅读