为给定元素构建数据验证属性列表

Build list of data validation attributes for a given element

使用 Input Extension Helper Methods, like @Html.TextboxFor, any Validation Attributes from your model are automatically generated by the Razor engine (via ClientValidationEnabled/UnobtrusiveJavaScriptEnabled) 中的任何一个时。

例如,采用以下情况,效果很好

型号:

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

查看:

@Html.TextBoxFor(model => model.QuestionOne) 
@Html.ValidationMessageFor(model => model.QuestionOne)

生成的标记:

<input type="text" id="QuestionOne" name="QuestionOne" value=""
       data-val="true" data-val-required="The QuestionOne field is required." > 
<span class="field-validation-valid" data-valmsg-for="QuestionOne" data-valmsg-replace="true"></span>

在这种情况下,属性 data-val="true"data-val-required="The QuestionOne field is required." 由非侵入式验证选取并且表单元素已成功验证。


但是,出于可扩展性的原因,我希望能够自己生成 <input> 元素而不是使用 TextBoxFor。所以我的视图现在看起来像这样:

<input type="textbox" 
       id="@Html.IdFor(m => m.QuestionTwo)"
       name="@Html.NameFor(m => m.QuestionTwo)" 
       value="@Model.QuestionTwo"
       data-val="true" data-val-required="Selection is Required" />

@Html.ValidationMessageFor(model => model.QuestionTwo)

在这种情况下,我只是通过手动重写 data-val="true" (etc) 来伪造验证属性输出,但这必须扩展以涵盖每一种情况。

Here's a running Demo in .NET Fiddle

问:我可以为给定元素构建 /return 一个 data-val-* 属性列表吗?

您可以使用 HtmlHelperGetUnobtrusiveValidationAttributes() 方法获取与特定 属性 关联的验证属性。

例如在视图中

@{ var attributes = Html.GetUnobtrusiveValidationAttributes("QuestionTwo"); }

<input 
    type="textbox"
    @foreach(var attr in attributes)
    {
        @:@attr.Key="@attr.Value"
    }
    id="@Html.IdFor(m => m.QuestionTwo)"
    ....
/>

请注意 @:@attr.Key="@attr.Value" 行会发出警告(缺少属性名称)但 运行 正确

或者,您可以使用 javaScript/jQuery 添加属性

<script type="text/javascript">
    var attributes = @Html.Raw(Json.Encode(attributes));
    var input = $('#QuestionTwo');
    for(var i in attributes) {
        input.attr(i, attributes[i]);
    }
</script>

我已经分叉 DotNetFiddle here 来显示两个选项的工作代码。

虽然上面的代码显示了如何完成,但您不应该那样做。 HtmlHelper 方法执行大量您忽略的代码以确保正确的双向模型绑定,例如,value 属性是通过首先检查 ModelState 中的值来确定的,然后在ViewDataDictionary,并且仅当先前的值不存在时,它才使用 属性 的值(TextBoxFor displaying initial value, not the value updated from code 的第二部分解释了该行为)。

除了不正确的 value 属性外,您为 <input> 显示的代码与仅使用 @Html.TextBoxFor(m => m.Question2) 生成的代码相同。我假设您的实际情况有所不同,但是如果您不能使用 TextBoxFor() 并使用接受 htmlAttributes 的重载来生成您需要的 html ,那么正确的方法是创建您的拥有 HtmlHelper 方法(并利用 HtmlHelper class 和 System.Web.Mvc.Html 命名空间中的现有方法)