将自定义 JsonConverter 添加到 Web API 会影响传递给自定义验证属性的字符串值

Posted

技术标签:

【中文标题】将自定义 JsonConverter 添加到 Web API 会影响传递给自定义验证属性的字符串值【英文标题】:Adding custom JsonConverter to Web API impacts string value passed to custom Validation Attribute 【发布时间】:2020-08-07 00:03:09 【问题描述】:

我有一个接受 json 请求的 ASP.NET Web API。使用默认的 JsonMediaTypeFormatter。

configuration.Formatters.Add(new JsonMediaTypeFormatter());

在模型上,我使用自定义 ValidationAttribute 来确保提供的字符串值与预期的日期时间格式匹配。有效值示例 = "2020-04-21T11:30:43+03:00"

我的模型中的代码 sn-p(显然包含更多属性):

[Required]
[DateFormat("yyyy-MM-ddTHH:mm:sszzz")]
public string RegistrationTimestamp  get; set; 

public string RegisteredValue  get; set; 

来自 DateFormat ValidationAttribute 的代码 sn-p 如下所示:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)

    if (value == null)
    
        return ValidationResult.Success;
    

    if (DateTime.TryParseExact((string)value, _dateFormat, new CultureInfo("nl-NL"), DateTimeStyles.AdjustToUniversal, out DateTime date))
    
        return ValidationResult.Success;
    

    return new ValidationResult($"Date provided [AntiXssEncoder.htmlEncode(value.ToString(), true)] is not formatted as [_dateFormat].");

以上工作正常。

我注意到,当一个空字符串值作为 RegisteredValue 提供时,它最终在模型中作为一个空字符串,而我希望在模型中将它们作为 null 代替。这就是为什么我决定引入一个自定义的 JsonConverter 来将空字符串转换为 null。

配置调整:

configuration.Formatters.Add(new JsonMediaTypeFormatter());
configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new EmptyStringToNullConverter());

实现了自定义的JsonConverter:

public class EmptyStringToNullConverter : JsonConverter

    public override bool CanConvert(Type objectType)    
    
        return objectType == typeof(string);
    

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    
        if (reader.Value == null)
        
            return null;
        

        var text = reader.Value.ToString();

        if (string.IsNullOrWhiteSpace(text))
        
            return null;
        

        return text;
    

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    
        throw new NotSupportedException("Not needed because this converter cannot write json");
    

    public override bool CanWrite
    
        get  return false; 
    

JsonConverter 的逻辑工作正常,它确保将空字符串转换为 null。不幸的是,添加此 JsonConverter 似乎会影响字符串值的解释方式,因为传递给 DateFormat ValidationAttribute 的值不再是提供给 API 的字符串值,而是从“2020-04-21T11:30:43+03: 00”变为“20 年 4 月 21 日 10:30:43”。

当此自定义 JsonConvertor 对日期解析不执行任何操作时,添加自定义 JsonConverter 如何影响传递给 ValidationAttribute 的值?

【问题讨论】:

【参考方案1】:

显然我不是第一个遇到这个问题的人,我在浏览 Newtonsoft.Json 包上的 GitHub 问题时发现:https://github.com/JamesNK/Newtonsoft.Json/issues/904

所以最终我最终将 DateParseHandling 设置为 None,同时保留了我的自定义 JsonConvertor。

configuration.Formatters.Add(new JsonMediaTypeFormatter());
configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new EmptyStringToNullConverter());
configuration.Formatters.JsonFormatter.SerializerSettings.DateParseHandling = DateParseHandling.None;

【讨论】:

以上是关于将自定义 JsonConverter 添加到 Web API 会影响传递给自定义验证属性的字符串值的主要内容,如果未能解决你的问题,请参考以下文章

将自定义标头添加到 AFNetworking,我做错了啥?

将自定义标记 (HTMLMarkers) 添加到聚类

如何将自定义挂钩添加到 Woocommerce 的自定义插件

AWS Elastic Beanstalk:将自定义日志添加到 CloudWatch?

将自定义 QWidget 添加到 QListWidget

将自定义 UIView 添加到 iCarousel