我想实现一个自定义JsonConverter来使用,
[JsonConverter(typeof(ArrayString))]
public string ServiceCodes { get; set; }
目的是将JSON数组转换为带分隔符的字符串,例如,
["this", "is", "my", "json", "array"]
应该成为"this;is;my;json;array"
(或任何分隔符)。同样,反过来应该是可能的。
我很难理解覆盖WriteJson
的{{1}}方法。
为了提供一些上下文,我JsonConverter
是实体上的属性(我正在使用EF6)。我认为,除了其他一对多实现之外,做我要求我的案例更容易。然而,我遇到的一个问题是JsonConverter何时被调用?
当getter需要json时,我只希望ServiceCodes
给json,即当包含此属性的对象从我的API返回为JSON时。例如,当我编写LINQ时,我不希望调用此转换器。
任何帮助将不胜感激,谢谢。
编辑 - 已添加信息
这是类和一些moc数据。
get
[ComplexType]
public class TerminalDuties
{
public string TerminalCode { get; set; }
public string TransportationCode { get; set; }
[JsonConverter(typeof(ArrayString))]
public string ServiceCodes { get; set; }
}
我试过了@ felix-b的答案,但它没有映射。该对象为null。我在ArrayString类中有断点,但它们没有被击中。据推测它没有尝试映射,因为属性是一个字符串。解决方法是什么?
以下是它在我的Web API Controller(从ApiController继承)中公开的方式
"Origin": {
"TerminalCode": "MIA",
"TransportationCode": "GT",
"ServiceCodes": ["WH", "HL"]
}
答案 0 :(得分:3)
使用.NET Framework 4.6.1,ASP.NET Web API 2,Entity Framework 6.1.3,Newtonsoft.Json 10.0.3进行测试。
<强>更新强>
我的答案最初需要指定[JsonConverter(typeof(ArrayString), ';')]
,而不是问题中的[JsonConverter(typeof(ArrayString))]
。
我在转换器类中添加了默认构造函数,因此分隔符配置是可选的,如果未指定,将使用分号。现在[JsonConverter(typeof(ArrayString))]
也可以。
原始回答
只有在通过JSON.NET对您的实体进行序列化和反序列化时才会调用转换器。它不影响从代码获取或设置属性值,也不影响LINQ查询和数据库操作。
这是转换器实现:
public class ArrayString : JsonConverter
{
private readonly char _delimiter;
// UPDATE -- added default constructor, so that
// JsonConverter attribute can be specified without the
// delimiter parameter, in which case semicolon will be used
public ArrayString() : this(';')
{
}
public ArrayString(char delimiter)
{
_delimiter = delimiter;
}
public override bool CanRead => true;
public override bool CanWrite => true;
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.StartArray)
{
return null;
}
var stringValue = new StringBuilder();
while (reader.Read() && reader.TokenType == JsonToken.String)
{
if (stringValue.Length > 0)
{
stringValue.Append(_delimiter);
}
stringValue.Append((string)reader.Value);
}
return stringValue.ToString();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var stringValue = value?.ToString();
if (stringValue == null)
{
writer.WriteNull();
return;
}
var arrayValue = stringValue.Split(_delimiter);
writer.WriteStartArray();
foreach (var item in arrayValue)
{
writer.WriteValue(item);
}
writer.WriteEndArray();
}
}
以下是如何指定分隔符(本例中的分号):
[JsonConverter(typeof(ArrayString), ';')]
public string ServiceCodes { get; set; }