针对子集合的流利验证 - 如何在 MVC 中显示错误消息
Fluent Validation against child collection - how to show error message in MVC
我有一个包含子集合的父模型。我的验证工作正常。我在页面上看到了子元素的错误消息。在来自服务器的 return 消息中,我看到集合的错误在结果消息中,但是由于 属性 本身没有映射到视图中,它没有绑定到 asp-验证-for.
这是我的代码:
型号:
public class TestModel
{
public List<TestChildModel> TestChildModels { get; set; }
public string Name { get; set; }
public string TestChildModelsErrorMessage { get; set; }
}
public class TestChildModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Count { get; set; }
}
控制器:
public class TestController : Controller
{
public IActionResult Index()
{
var tModel = new TestModel
{
Name = "Test 1",
TestChildModels = new List<TestChildModel>
{
new TestChildModel {Id = 1, Name = "Child 1", Count = 0},
new TestChildModel {Id = 2, Name = "Child 2", Count = 0},
new TestChildModel {Id = 2, Name = "Child 3", Count = 0},
}
};
return View(tModel);
}
[FormValidator]
public IActionResult Submit(TestModel testModel)
{
if (ModelState.IsValid)
{
return FormResult.CreateSuccessResult("Success");
}
else
{
return FormResult.CreateErrorResult("Error");
}
}
}
验证者:
public class TestModelValidator : AbstractValidator<TestModel>
{
public TestModelValidator()
{
RuleFor(x => x.Name).MaximumLength(10);
RuleFor(x => x.TestChildModels).Custom((list, context) =>
{
if (list.Sum(x => x.Count) < 3)
{
context.AddFailure("The 'Count' sum must be greater than 3.");
}
});
RuleForEach(x=>x.TestChildModels).SetValidator(new TestChildModelValidator());
}
}
public class TestChildModelValidator : AbstractValidator<TestChildModel>
{
public TestChildModelValidator()
{
RuleFor(x => x.Name).MaximumLength(15);
RuleFor(x => x.Count).GreaterThan(0);
}
}
查看:
@model ItemRequest.WebApplicationMVC.Models.TestModel
<form id="testForm" method="post" asp-formhelper="true" asp-controller="Test" asp-action="Submit">
<input asp-for="Name" />
<span asp-validation-for="Name" class="text-danger"></span>
@Html.EditorFor(m => m.TestChildModels)
<span asp-validation-for="TestChildModels" class="text-danger"></span>
<input type="submit" value="Soumettre" />
</form>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
EditorTemplates TestChildModel.cshtml
@model ItemRequest.WebApplicationMVC.Models.TestChildModel
<div class="row">
<div class="col-4">
<input asp-for="Id" />
<span asp-validation-for="Id" class="text-danger"></span>
</div>
<div class="col-4">
<input asp-for="Name" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="col-4">
<input asp-for="Count" />
<span asp-validation-for="Count" class="text-danger"></span>
</div>
</div>
这是我提交时的结果消息。
{"status":4,"message":null,"redirectUri":null,"redirectDelay":null,"object":null,
"validationErrors":[
{"propertyName":"TestChildModels","message":"The \u0027Count\u0027 sum must be greater than 3."},
{"propertyName":"TestChildModels[0].Count","message":"\u0027Count\u0027 doit \u00EAtre plus grand que \u00270\u0027."},
{"propertyName":"TestChildModels[1].Count","message":"\u0027Count\u0027 doit \u00EAtre plus grand que \u00270\u0027."},
{"propertyName":"TestChildModels[2].Count","message":"\u0027Count\u0027 doit \u00EAtre plus grand que \u00270\u0027."}],"isSucceed":false}
我在 javascript 文件中遇到错误,因为表单不包含名为 TestChildModels
的 属性。
我探索了几个解决方案但没有成功:为 TestChildModels
设置隐藏输入,尝试 return 另一个 属性 中的错误消息,但无法这样做。
我在 ASP.NET 核心 MVC 项目中使用 FluentValidation 和 FormHelper。 FluentValidation:https://fluentvalidation.net/ FormHelper : https://github.com/sinanbozkus/FormHelper 谢谢!
您可以尝试如下更改代码:
首先在你的 class 中添加 Error 属性:
public class TestModel
{
public List<TestChildModel> TestChildModels { get; set; }
public string Name { get; set; }
public string Error { get; set; }
public string TestChildModelsErrorMessage { get; set; }
}
然后像下面这样更改您的 TestModelValidator
:
public class TestModelValidator : AbstractValidator<TestModel>
{
public TestModelValidator()
{
RuleFor(x => x.Name).MaximumLength(10);
RuleFor(x => x.TestChildModels).Custom((list, context) =>
{
if (list.Sum(x => x.Count) < 3)
{
//context.AddFailure("The 'Count' sum must be greater than 3.");
context.AddFailure(new ValidationFailure("Error", "The 'Count' sum must be greater than 3."));
}
});
RuleForEach(x => x.TestChildModels).SetValidator(new TestChildModelValidator());
}
}
在您看来:
<form id="testForm" method="post" asp-formhelper="true" asp-controller="Test" asp-action="Submit">
<input asp-for="Name" />
<span asp-validation-for="Name" class="text-danger"></span>
@for (var i = 0; i < Model.TestChildModels.Count; i++)
{
@Html.EditorFor(model => model.TestChildModels[i])
}
<input type="hidden" asp-for="Error"/>
<span asp-validation-for="Error" class="text-danger"></span>
<input type="submit" value="Soumettre" />
测试结果:
我有一个包含子集合的父模型。我的验证工作正常。我在页面上看到了子元素的错误消息。在来自服务器的 return 消息中,我看到集合的错误在结果消息中,但是由于 属性 本身没有映射到视图中,它没有绑定到 asp-验证-for.
这是我的代码: 型号:
public class TestModel
{
public List<TestChildModel> TestChildModels { get; set; }
public string Name { get; set; }
public string TestChildModelsErrorMessage { get; set; }
}
public class TestChildModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Count { get; set; }
}
控制器:
public class TestController : Controller
{
public IActionResult Index()
{
var tModel = new TestModel
{
Name = "Test 1",
TestChildModels = new List<TestChildModel>
{
new TestChildModel {Id = 1, Name = "Child 1", Count = 0},
new TestChildModel {Id = 2, Name = "Child 2", Count = 0},
new TestChildModel {Id = 2, Name = "Child 3", Count = 0},
}
};
return View(tModel);
}
[FormValidator]
public IActionResult Submit(TestModel testModel)
{
if (ModelState.IsValid)
{
return FormResult.CreateSuccessResult("Success");
}
else
{
return FormResult.CreateErrorResult("Error");
}
}
}
验证者:
public class TestModelValidator : AbstractValidator<TestModel>
{
public TestModelValidator()
{
RuleFor(x => x.Name).MaximumLength(10);
RuleFor(x => x.TestChildModels).Custom((list, context) =>
{
if (list.Sum(x => x.Count) < 3)
{
context.AddFailure("The 'Count' sum must be greater than 3.");
}
});
RuleForEach(x=>x.TestChildModels).SetValidator(new TestChildModelValidator());
}
}
public class TestChildModelValidator : AbstractValidator<TestChildModel>
{
public TestChildModelValidator()
{
RuleFor(x => x.Name).MaximumLength(15);
RuleFor(x => x.Count).GreaterThan(0);
}
}
查看:
@model ItemRequest.WebApplicationMVC.Models.TestModel
<form id="testForm" method="post" asp-formhelper="true" asp-controller="Test" asp-action="Submit">
<input asp-for="Name" />
<span asp-validation-for="Name" class="text-danger"></span>
@Html.EditorFor(m => m.TestChildModels)
<span asp-validation-for="TestChildModels" class="text-danger"></span>
<input type="submit" value="Soumettre" />
</form>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
EditorTemplates TestChildModel.cshtml
@model ItemRequest.WebApplicationMVC.Models.TestChildModel
<div class="row">
<div class="col-4">
<input asp-for="Id" />
<span asp-validation-for="Id" class="text-danger"></span>
</div>
<div class="col-4">
<input asp-for="Name" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="col-4">
<input asp-for="Count" />
<span asp-validation-for="Count" class="text-danger"></span>
</div>
</div>
这是我提交时的结果消息。
{"status":4,"message":null,"redirectUri":null,"redirectDelay":null,"object":null,
"validationErrors":[
{"propertyName":"TestChildModels","message":"The \u0027Count\u0027 sum must be greater than 3."},
{"propertyName":"TestChildModels[0].Count","message":"\u0027Count\u0027 doit \u00EAtre plus grand que \u00270\u0027."},
{"propertyName":"TestChildModels[1].Count","message":"\u0027Count\u0027 doit \u00EAtre plus grand que \u00270\u0027."},
{"propertyName":"TestChildModels[2].Count","message":"\u0027Count\u0027 doit \u00EAtre plus grand que \u00270\u0027."}],"isSucceed":false}
我在 javascript 文件中遇到错误,因为表单不包含名为 TestChildModels
的 属性。
我探索了几个解决方案但没有成功:为 TestChildModels
设置隐藏输入,尝试 return 另一个 属性 中的错误消息,但无法这样做。
我在 ASP.NET 核心 MVC 项目中使用 FluentValidation 和 FormHelper。 FluentValidation:https://fluentvalidation.net/ FormHelper : https://github.com/sinanbozkus/FormHelper 谢谢!
您可以尝试如下更改代码:
首先在你的 class 中添加 Error 属性:
public class TestModel
{
public List<TestChildModel> TestChildModels { get; set; }
public string Name { get; set; }
public string Error { get; set; }
public string TestChildModelsErrorMessage { get; set; }
}
然后像下面这样更改您的 TestModelValidator
:
public class TestModelValidator : AbstractValidator<TestModel>
{
public TestModelValidator()
{
RuleFor(x => x.Name).MaximumLength(10);
RuleFor(x => x.TestChildModels).Custom((list, context) =>
{
if (list.Sum(x => x.Count) < 3)
{
//context.AddFailure("The 'Count' sum must be greater than 3.");
context.AddFailure(new ValidationFailure("Error", "The 'Count' sum must be greater than 3."));
}
});
RuleForEach(x => x.TestChildModels).SetValidator(new TestChildModelValidator());
}
}
在您看来:
<form id="testForm" method="post" asp-formhelper="true" asp-controller="Test" asp-action="Submit">
<input asp-for="Name" />
<span asp-validation-for="Name" class="text-danger"></span>
@for (var i = 0; i < Model.TestChildModels.Count; i++)
{
@Html.EditorFor(model => model.TestChildModels[i])
}
<input type="hidden" asp-for="Error"/>
<span asp-validation-for="Error" class="text-danger"></span>
<input type="submit" value="Soumettre" />
测试结果: