我们使用的是.NET Core 3.1
。我们有一个用于DateTime
和DateTime?
属性的自定义JSON转换器。
JsonDateTimeConverter.cs
public class JsonDateTimeConverter : DateTimeConverterBase
{
public override bool CanConvert(Type objectType)
{
// I want to return false for object properties which have attribute "TimeZoneIgnore"
return objectType == typeof(DateTime) || objectType == typeof(DateTime?);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// convert datetime to timezone
DateTime? dateTime = (value as DateTime?).ConvertToTimeZone("CEST");
writer.WriteValue(dateTime);
writer.Flush();
}
}
TimeZoneIgnore.cs
[AttributeUsage(AttributeTargets.Property)]
public class TimeZoneIgnore : Attribute { }
Bank.cs
public class Bank
{
public string Name { get; set; }
public DateTime ConvertThis { get; set; }
[TimeZoneIgnore]
public DateTime DontConvertThis { get; set; }
}
TestController.cs
[HttpGet]
public IActionResult Test123()
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new JsonDateTimeConverter());
return Json(new Bank()
{
Name = "Test bank",
ConvertThis = new DateTime(2020, 8, 18, 15, 7, 1),
DontConvertThis = new DateTime(2020, 8, 18, 15, 7, 1)
}, settings);
}
对于具有TimeZoneIgnore
属性的对象属性,如何在CanConvert(Type objectType)
中返回false
?
JsonConverter
没有上下文来确定它要应用到哪个属性,因此没有一种简单的方法可以从中获取属性。另一方面,ContractResolver
确实有上下文信息,因为它负责将JSON属性映射到类属性。事实证明,您还可以使用ContractResolver
以编程方式应用或删除JsonConverters
。
因此,您可以使用自定义ContractResolver
根据[TimeZoneIgnore]
属性的存在与否有条件地应用它,而不是在设置中全局应用JsonDateTimeConverter
。以下是解析程序所需的代码:
public class ConditionalDateTimeResolver : DefaultContractResolver
{
static readonly JsonConverter DateTimeConverter = new JsonDateTimeConverter();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
if (DateTimeConverter.CanConvert(prop.PropertyType) &&
!prop.AttributeProvider.GetAttributes(typeof(TimeZoneIgnore), true).Any())
{
prop.Converter = DateTimeConverter;
}
return prop;
}
}
要使用解析器,请将其添加到JsonSerializerSettings
,而不是添加转换器:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new ConditionalDateTimeResolver();
// settings.Converters.Add(new JsonDateTimeConverter()); <-- remove this line
以下是一个工作演示:https://dotnetfiddle.net/8LBZ4S