我正在查询一个服务,该服务以多种格式返回标签列表:
{
"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; }
}
这有效,但仅适用于以空格分隔的标签。
但是,如果我能够以参数化方式更改
TagsConverter
和Split
函数,则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; }
}