【问题标题】:How can I customize the deserialization of a nested property in Json.net without adding attributes如何在不添加属性的情况下自定义 Json.net 中嵌套属性的反序列化
【发布时间】:2020-03-10 05:22:13
【问题描述】:

假设我有这些课程:

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,我无法在嵌套属性上注册 JsonConverter

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

  • 请注意,我不仅需要为 Bar 类执行此操作,还需要为无限数量的结构未知的类执行此操作,因此我无法硬编码适用于一种类的解决方案。

【问题讨论】:

标签: c# json.net json-deserialization


【解决方案1】:

根据您的描述,我不明白您为什么需要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() 方法,如下所示:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    相关资源
    最近更新 更多