考虑以下课程:
public class Person
{
[DisplayFormat(DataFormatString = "dd/MM/yyyy")]
public DateTime DOB { get; set; }
}
当使用Json.NET将对象序列化为JSON时,如果属性使用DisplayFormatAttribute
进行修饰,我希望覆盖序列化。这应该有效地呼吁:
object toBeSerialized = DOB.ToString(attribute.DateFormatString)
有效地返回格式化字符串而不是DateTime
。
使用Json.NET实现此目的的推荐方法是什么?
答案 0 :(得分:3)
JsonConverter
类无权访问属性声明,因此无法获取它所装饰的属性。
此外,无法使用自定义JsonConverter
装饰您的属性,并将其传递给您要使用的日期格式,因为您应该传递类型你想要使用的JsonConverter,而不是实例:
// This doesn't help us...
[JsonConverter(typeof(CustomDateTimeFormatConverter)]
public DateTime DOB { get; set; }
那我们该怎么做?
为了将格式字符串传递给我们的转换器,我们可以通过以下ContractResolver
(通过反射访问属性信息)将其关联起来:
public class CustomDateTimeFormatResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
// skip if the property is not a DateTime
if (property.PropertyType != typeof (DateTime))
{
return property;
}
var attr = (DisplayFormatAttribute)member.GetCustomAttributes(typeof(DisplayFormatAttribute), true).SingleOrDefault();
if (attr != null)
{
var converter = new IsoDateTimeConverter();
converter.DateTimeFormat = attr.DataFormatString;
property.Converter = converter;
}
return property;
}
}
这将使用IsoDateTimeConverter
属性中指定的格式将DisplayFormat
转换器与我们的自定义DateTimeFormat关联到运行时的日期时间。
为了告诉Json.NET使用我们的ContractResolver,我们需要在序列化为json时使用这种语法:
string json = JsonConvert.SerializeObject(
p, Formatting.Indented,
new JsonSerializerSettings
{ ContractResolver = new CustomDateTimeFormatResolver() });