将自定义 JsonConverter 添加到 Web API 会影响传递给自定义验证属性的字符串值
Adding custom JsonConverter to Web API impacts string value passed to custom Validation Attribute
我有一个 ASP.NET Web API 可以接受 json 请求。使用默认的 JsonMediaTypeFormatter。
configuration.Formatters.Add(new JsonMediaTypeFormatter());
在模型上,我使用自定义 ValidationAttribute 来确保提供的字符串值与预期的日期时间格式匹配。有效值示例 = "2020-04-21T11:30:43+03:00"
我模型中的代码片段(显然包含更多属性):
[Required]
[DateFormat("yyyy-MM-ddTHH:mm:sszzz")]
public string RegistrationTimestamp { get; set; }
public string RegisteredValue { get; set; }
DateFormat ValidationAttribute 的代码片段如下所示:
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”变成“21-Apr-20 10:30:43”。
当此自定义 JsonConverter 对日期解析不执行任何操作时,添加自定义 JsonConverter 如何影响传递给 ValidationAttribute 的值?
显然我不是第一个遇到这个问题的人,因为我在浏览 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;
我有一个 ASP.NET Web API 可以接受 json 请求。使用默认的 JsonMediaTypeFormatter。
configuration.Formatters.Add(new JsonMediaTypeFormatter());
在模型上,我使用自定义 ValidationAttribute 来确保提供的字符串值与预期的日期时间格式匹配。有效值示例 = "2020-04-21T11:30:43+03:00"
我模型中的代码片段(显然包含更多属性):
[Required]
[DateFormat("yyyy-MM-ddTHH:mm:sszzz")]
public string RegistrationTimestamp { get; set; }
public string RegisteredValue { get; set; }
DateFormat ValidationAttribute 的代码片段如下所示:
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”变成“21-Apr-20 10:30:43”。
当此自定义 JsonConverter 对日期解析不执行任何操作时,添加自定义 JsonConverter 如何影响传递给 ValidationAttribute 的值?
显然我不是第一个遇到这个问题的人,因为我在浏览 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;