簡體   English   中英

忽略自定義 JSON 轉換器中具有屬性的屬性

[英]Ignore property with attribute in custom JSON converter

我們正在使用.NET Core 3.1 我們有一個用於DateTimeDateTime? 特性。

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 { }

銀行.cs

public class Bank
{
    public string Name { get; set; }
    public DateTime ConvertThis { get; set; }
    [TimeZoneIgnore]
    public DateTime DontConvertThis { get; set; }
}

測試控制器.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屬性的 object 屬性,如何在CanConvert(Type objectType)中返回false

JsonConverter沒有上下文來確定它應用於哪個屬性,因此沒有一種簡單的方法可以從其中獲取屬性。 另一方面, ContractResolver確實具有上下文信息,因為它負責將 JSON 屬性映射到 class 屬性。 事實證明,您還可以使用ContractResolver以編程方式應用或刪除JsonConverters

因此,不是在設置中全局應用JsonDateTimeConverter ,而是可以使用自定義ContractResolver根據是否存在[TimeZoneIgnore]屬性有條件地應用它。 這是解析器所需的代碼:

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://do.netfiddle.net/8LBZ4S

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM