ASP.NET Core +客户端验证:如果ViewBag和Model具有相同的属性名称,则不会生成data-val- *属性

问题描述 投票:1回答:1

我在ASP.NET Core 2.2中意识到,如果ViewBag和Model具有相同的属性名称,则不会生成data-val- *属性(在我的情况下,它是关于属性的“Title”)。由于缺少data-val- *属性,客户端验证不起作用。

这是我的模特:

public class ActivityModel
{
    public int Id { get; set; }

    [Required]
    public string Title { get; set; }
}

这是我的观点:

@model ActivityModel

@{ ViewBag.Title = "This is my title"; }  

@using (Html.BeginForm("Create", "Activities"))
{
    @Html.EditorFor(model => model.Title)

    <input type="submit" value="Create" class="btn btn-default" />
}

@section Scripts {
    @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
}

ViewBag.Title属性在_layout.cshtml中用于显示当前标题名称。

如果我将ViewBag或Model属性名称更改为其他内容,则会生成data-val- *属性并且客户端验证可以正常工作。

从技术角度来看是什么导致了这种行为?

asp.net asp.net-core unobtrusive-validation viewbag client-side-validation
1个回答
0
投票

虽然我无法弄清楚为什么会发生这种情况的确切原因,但我可以建议你一些解决方法。显而易见的是在渲染输入后分配ViewBag

@using (Html.BeginForm("Create", "Activities"))
{
    @Html.EditorFor(model => model.Title)
    <input type="submit" value="Create" class="btn btn-default" />
} 

@{ ViewBag.Title = "This is my title"; }  

或者你可以使用input tag helper,因为它不会遇到这个问题

 <input asp-for="Title" />
 <input type="submit" value="Create" class="btn btn-default" />

可能很有趣

您可以通过在剃刀视图中将ViewContext.ClientValidationEnabled设置为false来禁用添加客户端验证属性(这很明显)

@{
    ViewContext.ClientValidationEnabled = false;
}

如果由于某种原因,您需要为同一属性渲染超过1个input,并验证以下代码

@Html.EditorFor(model => model.Title)
@Html.EditorFor(model => model.Title)

将不会对第二个input进行验证

<input class="text-box single-line" data-val="true" data-val-required="The Title field is required." id="Title" name="Title" type="text" value="Activity">
<input class="text-box single-line" id="Title" name="Title" type="text" value="Activity">

发生这种情况是因为渲染器跟踪渲染的属性并阻止对同一属性多次添加验证。这些属性由ViewContext.FormContext跟踪,因此可以控制此行为。在添加验证属性之前,渲染器检查属性是否通过调用ViewContext.FormContext.RenderedField(propertyName)呈现,如果呈现属性,则调用ViewContext.FormContext.RenderedField(propertyName, true)将属性标记为已呈现。但你可以像这样用false调用这个方法

@Html.EditorFor(model => model.Title)
@{
    ViewContext.FormContext.RenderedField("Title", false);
}
@Html.EditorFor(model => model.Title)

这给出了以下结果

<input class="text-box single-line" data-val="true" data-val-required="The Title field is required." id="Title" name="Title" type="text" value="Activity">
<input class="text-box single-line" data-val="true" data-val-required="The Title field is required." id="Title" name="Title" type="text" value="Activity">
© www.soinside.com 2019 - 2024. All rights reserved.