针对子集合的流利验证 - 如何在 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" />

测试结果: