我正在查询一个服务,该服务以多种格式返回标签​​列表:

{
  "tags": "a,b,c"
}


要么

{
  "tags": "a b c"
}


要么

{
  "tags": "a+b+c"
}


我要反序列化的对象是List<string>。我写了一个TagsConverter,它实现了JsonConverter中的必要方法,如下所示:

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return reader
                .Value
                .ToString()
                .Split(' ')
                .ToList();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var list = (List<string>)value;
        var delimitedList = string.Join(" ", list);

        writer.WriteValue(delimitedList);
    }
}


然后,我对对象中的字段进行注释,如下所示:

public class Foo
{
  [JsonConverter(typeof(TagsConverter))]
  public List<string> Tags { get; set; }
}


这有效,但仅适用于以空格分隔的标签。

但是,如果我能够以参数化方式更改TagsConverterSplit函数,则Join可以在所有3种情况下工作。但是由于我们仅将类型传递给JsonConverter属性,所以我知道我们不能在此处传递“定界符”作为参数。

有什么办法可以做到这一点?

最佳答案

还有一个附加的JsonConverter constructor overload,它同时包含类型和params object[] converterParameters,它们被插入转换器的具体实例中。您可以利用此重载来最大化可重用性。

public class TagsConverter : JsonConverter
{
    private readonly string _delimiter;

    public TagsConverter(string delimiter)
    {
        _delimiter = delimiter;
    }

    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(string));
    }

    public override object ReadJson(JsonReader reader, Type objectType,
        object existingValue, JsonSerializer serializer)
    {
        return reader
                .Value
                .ToString()
                .Split(_delimiter.ToCharArray())
                .ToList();
    }

    public override void WriteJson(JsonWriter writer, object value,
        JsonSerializer serializer)
    {
        var list = (List<string>)value;
        var delimitedList = string.Join(_delimiter, list);

        writer.WriteValue(delimitedList);
    }
}


利用重载就像传递第二个参数一样容易:

public class Foo
{
    [JsonConverter(typeof(TagsConverter), " ")]
    public List<string> Tags { get; set; }
}

10-06 06:27