问题是通过[JsonConverter(typeof(IsoDateTimeConverter))] 应用的转换器取代 传递给序列化程序的转换器。这记录在Serialization Attributes: JsonConverterAttribute:
JsonConverterAttribute
指定哪个
JsonConverter
用于转换对象。
属性可以放在类或成员上。当放置在
类,该属性指定的 JsonConverter 将是
序列化该类的默认方式。当属性在
字段或属性,则指定的 JsonConverter 将始终为
用于序列化该值。
使用JsonConverter的优先级是成员属性,那么
类属性,最后是传递给
JsonSerializer。
作为一种解决方法,在应用转换器的ReadJson() 和WriteJson() 方法中,可以在序列化程序的转换器列表中检查相关转换器,如果找到,则使用它。装饰器模式可用于将此逻辑与底层转换逻辑分开。一、介绍:
public class OverridableJsonConverterDecorator : JsonConverterDecorator
{
public OverridableJsonConverterDecorator(Type jsonConverterType) : base(jsonConverterType) { }
public OverridableJsonConverterDecorator(JsonConverter converter) : base(converter) { }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
foreach (var converter in serializer.Converters)
{
if (converter == this)
{
Debug.WriteLine("Skipping identical " + converter.ToString());
continue;
}
if (converter.CanConvert(value.GetType()) && converter.CanWrite)
{
converter.WriteJson(writer, value, serializer);
return;
}
}
base.WriteJson(writer, value, serializer);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
foreach (var converter in serializer.Converters)
{
if (converter == this)
{
Debug.WriteLine("Skipping identical " + converter.ToString());
continue;
}
if (converter.CanConvert(objectType) && converter.CanRead)
{
return converter.ReadJson(reader, objectType, existingValue, serializer);
}
}
return base.ReadJson(reader, objectType, existingValue, serializer);
}
}
public abstract class JsonConverterDecorator : JsonConverter
{
readonly JsonConverter converter;
public JsonConverterDecorator(Type jsonConverterType) : this((JsonConverter)Activator.CreateInstance(jsonConverterType)) { }
public JsonConverterDecorator(JsonConverter converter)
{
if (converter == null)
throw new ArgumentNullException();
this.converter = converter;
}
public override bool CanConvert(Type objectType)
{
return converter.CanConvert(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return converter.ReadJson(reader, objectType, existingValue, serializer);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
converter.WriteJson(writer, value, serializer);
}
public override bool CanRead { get { return converter.CanRead; } }
public override bool CanWrite { get { return converter.CanWrite; } }
}
然后,将装饰器应用到IsoDateTimeConverter 之上,如下所示:
[DataContract]
class x
{
[DataMember]
[JsonConverter(typeof(OverridableJsonConverterDecorator), typeof(IsoDateTimeConverter))]
public DateTime datum = new DateTime(1232, 3, 23);
}
现在静态应用的转换器将根据需要被取代。示例fiddle。
请注意,对于这个特定的测试用例,从Json.NET 4.5.1 开始,日期默认在 ISO 中序列化,并且不再需要 IsoDateTimeConverter。强制日期以特定格式序列化可以通过设置JsonSerializerSettings.DateFormatString来完成:
[DataContract]
class x
{
[DataMember]
public DateTime datum = new DateTime(1232, 3, 23);
}
var settings = new JsonSerializerSettings { DateFormatString = "yy" };
var json1 = JsonConvert.SerializeObject(new x(), settings);
Console.WriteLine(json1); // Prints {"datum":"32"}
var json2 = JsonConvert.SerializeObject(new x());
Console.WriteLine(json2); // Prints {"datum":"1232-03-23T00:00:00"}
示例fiddle。不过,一般问题值得回答。