The JsonConverter
class does not have access to the property declaration, so it has no way to get the attributes it is decorated with.
Also, there is no way to decorate your property with a custom JsonConverter
, and pass it the date format you want to use, because you are supposed to pass the type of the JsonConverter you want to use, and not the instance:
// This doesn't help us...
[JsonConverter(typeof(CustomDateTimeFormatConverter)]
public DateTime DOB { get; set; }
So how can we do ?
In order to pass a format string to our Converter, we can associate it through the following ContractResolver
(which has access to the property info through reflection):
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;
}
}
This will associate an IsoDateTimeConverter
converter with our custom DateTimeFormat to our datetime at runtime, using the format specified in the DisplayFormat
attribute.
And in order to tell Json.NET to use our ContractResolver, we need to use this syntax when serializing to json:
string json = JsonConvert.SerializeObject(
p, Formatting.Indented,
new JsonSerializerSettings
{ ContractResolver = new CustomDateTimeFormatResolver() });