我正在使用Fluent Validation来验证这个模型:
class MyModel {
public int Id {get; set;}
public List<ChildModel> Children {get; set;}
}
class ChildModel {
public int CId {get; set;}
public string Name {get; set;}
}
如果我添加这样的验证:
public class MyModelValidator : AbstractValidator<MyModel>
{
public MyModelValidator()
{
RuleForEach(x => x.Children)
.SetValidator(new ChildValidator());
}
}
public class ChildValidator : AbstractValidator<ChildModel>
{
public ChildValidator()
{
RuleFor(r => r.Name).NotEmpty();
}
}
这个模型和验证器,在验证错误的情况下,将给出这样的响应:
{
.....
"Children[0].Name": [
"'Name' must not be empty."
],
"Children[1].Name": [
"'Name` must not be empty."
]
.....
}
我想知道如何用验证失败的同一项目的CId
值替换验证响应中的Children
,像这样:
{
.....
"12345[0].Name": [
"'Name' must not be empty."
],
"99887[1].Name": [
"'Name` must not be empty."
]
.....
}
12345
和99887
为Children
(索引0项和索引1项)项CId
的值。
foreach语句中的验证消息的默认格式为
<collectionPropertyName>[<index>].<itemPropertyName>: <error message>
// Example:
// Children[0].Name: 'Name' must not be empty.
如果你想修改'list prefix',可以
- 用
OverridePropertyName()
覆盖集合属性名。例如,你可以将其设置为单数,但不能将其设置为空 - 用
OverrideIndexer()
覆盖索引器并将'[0]'替换为您喜欢的内容
例子:
RuleFor(r => r.Children)
.ForEach(r => r
.OverrideIndexer((model, collection, element, index) => " " + element.CId?.ToString())
.SetValidator(new ChildValidator())
)
.OverridePropertyName("Child");
// Example:
// Child 1234.Name: 'Name' must not be empty.
如果验证消息没有以'collectionPropertyName[index]'格式返回给using代码(api,单元测试,…),并且你想操作'错误消息'本身,你可以在子验证器类中重写'Validate'方法,如:
public override ValidationResult Validate(ValidationContext<ChildDto> context)
{
var result = base.Validate(context);
result.Errors.ForEach(e => AddMessagePrefix(e, context));
return result;
}
public override async Task<ValidationResult> ValidateAsync(ValidationContext<ChildDto> context, CancellationToken cancellation = default)
{
var result = await base.ValidateAsync(context, cancellation);
result.Errors.ForEach(e => AddMessagePrefix(e, context));
return result;
}
private void AddMessagePrefix(ValidationFailure failure, ValidationContext<ChildDto> context)
{
if (context.InstanceToValidate != null)
failure.ErrorMessage = $"Child {context.InstanceToValidate.CId}: {failure.ErrorMessage}";
}
// Example:
// Child 1234: 'Name' must not be empty.