【问题标题】:Build list of data validation attributes for a given element为给定元素构建数据验证属性列表
【发布时间】:2017-08-17 08:48:36
【问题描述】:

当使用任何Input Extension Helper Methods(如@Html.TextboxFor)时,Razor 引擎会自动生成模型中的任何Validation Attributes(通过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." 被非侵入式验证拾取,并且表单元素被成功验证。


但是,出于可扩展性的原因,我希望能够自己生成&lt;input&gt; 元素,而不是使用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

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

【问题讨论】:

  • HtmlHelper 有一个返回data-* 属性的GetUnobtrusiveValidationAttributes() 方法(但您需要从表达式中获取ModelMetaData)。您所显示的只是 TextBoxFor() 方法生成的完全相同的 html,除了 value 属性如果属性无效(因为您不再正确绑定)。你想用这个实现什么?
  • 我的用途更多样化。我想找到一种方法来向this custom &lt;select&gt; elementthis &lt;input typed="checked"&gt; 元素添加验证。
  • 我知道第一个是你的,但这是一个丑陋的解决方案。在这种情况下处理创建自定义 html 的方法是创建你自己的扩展方法,你可以访问 ModelMetadataHtmlHelper 方法,并且可以完全控制您的 html(在该示例中,视图代码将是(比如说)@Html.GeoDropdownListFor(m=&gt; m.CityId, Model.Cities);
  • @Stephen 我和 OP 有类似的失误。我的麻烦是我不知道如何正确实现我自己的 HTML 助手。我只需要处理源代码,这绝对是一场噩梦,充斥着如此多的回调,我很难找到实际的逻辑。
  • 你没有尝试GetUnobtrusiveValidationAttributes()的方法吗?还是你不明白怎么用?

标签: asp.net-mvc razor unobtrusive-validation


【解决方案1】:

您可以使用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 方法执行大量您忽略的代码以确保正确的 2 向模型绑定,例如,value 属性是通过首先检查 ModelState 中的值来确定的,然后是 ViewDataDictionary 中的值,并且仅当先前的值不存在时,才使用属性的值(TextBoxFor displaying initial value, not the value updated from code 的第二部分解释了行为)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多