Fluentvalidation错误消息包含c#属性名而不是客户端json属性名
本文关键字:属性 客户端 json 错误 包含 Fluentvalidation 消息 | 更新日期: 2023-09-27 18:01:21
我有一个c# WebApi项目,我正在使用FluentValidation。用于验证客户端输入的WebApi包。
下面是我的模型类代码,它的c#属性名为"IsPremium"。这个属性的json名称为"isLuxury"。
[Serializable, JsonObject, Validator(typeof(ProductValidator))]
public class Product
{
[JsonProperty("isLuxury")]
public bool? IsPremium { get; set; }
}
验证器类是这样的
public class ProductValidator : AbstractValidator<Product>
{
public ProductValidator()
{
RuleFor(product => product.isPremium).NotNull();
}
}
对于这样的请求:http://localhost: 52664/api/产品
请求主体:{"isLuxury":"}
我得到以下错误:
{
"Message": "The request is invalid.",
"ModelState": {
"product.isPremium": [
"'is Premium' must not be empty."
]
}
}
Fluent在这里选择c#属性名,这对客户端来说没有意义,因为它知道它是"isLuxury"。我怎样才能强制流畅地从json属性而不是c#属性中挑选名字,以提供更好的验证,如"'isLuxury'一定不能为空"?
如果不可能,我将不得不重命名我所有的c#属性有相同的名称,这些json暴露给所有的客户端。如果你有更好的方法来解决这个问题,请建议。
使用OverridePropertyName
方法修改验证器类
public class ProductValidator : AbstractValidator<Product>
{
public ProductValidator()
{
RuleFor(product => product.isPremium).NotNull().OverridePropertyName("isLuxury");
}
}
引用:https://github.com/JeremySkinner/FluentValidation/wiki/d.-Configuring-a-Validator overriding-the-default-property-name
或者您可以调用WithName
方法,它做类似的事情。如果你想完全重命名属性,我会使用OverridePropertyName
方法。
正如Sahil所说,使用OverridePropertyName方法。如果您还将它与此结合使用,它会自动计算出JSON属性名称:
private string GetJsonPropertyName<T>(string propertyName)
{
string jsonPropertyName =
typeof(T).GetProperties()
.Where(p => p.Name == propertyName)
.Select(p => p.GetCustomAttribute<JsonPropertyAttribute>())
.Select(jp => jp.PropertyName)
.FirstOrDefault();
if (null == jsonPropertyName)
{
throw new ArgumentException($"Type {nameof(T)} does not contain a property named {propertyName}");
}
return jsonPropertyName;
}
然后像这样使用:
RuleFor(product => product.IsPremium)
.NotNull()
.OverridePropertyName(
GetJsonPropertyName<Product>(nameof(Product.IsPremium))
);