我如何在Json.net中自定义嵌套属性的反序列化而不添加属性

问题描述 投票:0回答:1

假设我有那些课程:

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

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

而且我有这个Json结构:

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

而且我有一个代码路径,其中的JObject使用如下代码转换为Bar:

myJObject.ToObject(typeof(Bar))

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

我被要求不要在客户端类'Bar'上添加属性,因此环顾四周似乎是'ContractResolver'的问题,但问题是,解析器仅允许我处理根类型的直接属性,即在我的示例中为“ Bar”,并且我无法在嵌套属性上注册Converter。

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

  • [请注意,我不仅需要对'Bar'类执行此操作,而且还需要对数量不限的结构未知的类执行此操作,因此我无法对适用于一种类型的类的解决方案进行硬编码。
c# json.net json-deserialization
1个回答
0
投票

根据您的描述,我不明白您为什么需要ContractResolver。您知道要反序列化的属性将始终为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一起使用,创建一个新的JsonSerializer实例,向其添加转换器,然后将串行器传递给ToObject<T>()方法,如下所示:

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

var bar = myJObject.ToObject<Bar>(serializer);
© www.soinside.com 2019 - 2024. All rights reserved.