忽略自定义JSON转换器中具有属性的属性



我们使用的是.NET Core 3.1。我们有一个用于DateTimeDateTime?属性的自定义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

最新更新