【问题标题】:EditorFor not rendering data validation attributes without BeginFormEditorFor 在没有 BeginForm 的情况下不呈现数据验证属性
【发布时间】:2011-06-19 06:46:00
【问题描述】:

在 MVC 应用程序中,我想动态渲染表单的某些部分(例如 Controller 端的 PartialView)

在部分视图中,我没有 Html.BeginForm(),因为表单标签已经呈现。

@model Introduction.Models.Human
<div>
    @Html.EditorFor(model => model.MarriageInformation.SpouseDetails)
    <div class="editor-label">
        @Html.LabelFor(model => model.MarriageInformation.DOM)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.MarriageInformation.DOM)
        @Html.ValidationMessageFor(model => model.MarriageInformation.DOM)
    </div>
</div>

我面临的问题是在这种情况下 EditorFor 不返回所有 data-val-* 属性。

<div>
   <div class="editor-label">
    <label for="MarriageInformation_SpouseDetails_Name">Name</label>
</div>
<div class="editor-field"><input class="text-box single-line" id="MarriageInformation_SpouseDetails_Name" name="MarriageInformation.SpouseDetails.Name" type="text" value="" /> 

这是设计使然还是我在这里遗漏了什么?这里有什么工作吗?

我正在考虑的选项是在 ajax 加载之后 - 剥离表单并注入内部内容。

【问题讨论】:

    标签: c# asp.net-mvc-3


    【解决方案1】:

    您认为这是设计使然是正确的。如果您检查source,您将看到以下内容:

    // Only render attributes if unobtrusive client-side validation is enabled, and then only if we've
    // never rendered validation for a field with this name in this form. Also, if there's no form context,
    // then we can't render the attributes (we'd have no <form> to attach them to).
    public IDictionary<string, object> GetUnobtrusiveValidationAttributes(string name, ModelMetadata metadata)
    

    为了解决这个问题,我们可以编写一个扩展方法用于我们的局部视图:

    public static class HtmlExtentions
    {
        public static void EnablePartialViewValidation(this HtmlHelper helper)
        {
            if (helper.ViewContext.FormContext == null)
            {
                helper.ViewContext.FormContext = new FormContext();
            }
        }
    }
    

    然后在我们的局部视图中使用它:

    @model Introduction.Models.Human
    @{ Html.EnablePartialViewValidation(); }
    <div>
        @Html.EditorFor(model => model.MarriageInformation.SpouseDetails)
        <div class="editor-label">
            @Html.LabelFor(model => model.MarriageInformation.DOM)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.MarriageInformation.DOM)
            @Html.ValidationMessageFor(model => model.MarriageInformation.DOM)
        </div>
    </div>
    

    最后一步是在我们的 ajax 回调中处理解析新的验证属性:

    $(function () {
        $('button').click(function (e) {
            e.preventDefault();
            $.get('@Url.Action("AddSpouse")', function (resp) { 
                var $form = $('form');
                $form.append(resp);                    
                $form.removeData("validator").removeData("unobtrusiveValidation");
                $.validator.u‌​nobtrusive.parse($form);
            })
        })
    });
    

    【讨论】:

    • 为了扩展答案,我发现仅仅$.validate.unobtrusive.parse($form); 是不够的。我的最终代码看起来像$form.removeData("validator").removeData("unobtrusiveValidation");$.validator.unobtrusive.parse($form);。检查相关问题 - stackoverflow.com/q/4406291/655085
    • +1 for if (helper.ViewContext.FormContext == null){helper.ViewContext.FormContext = new FormContext();},它帮助我解决了其他问题
    【解决方案2】:

    如果您希望数据验证标签存在,您需要在FormContext 中。因此,如果您要动态生成部分表单,则需要在局部视图中包含以下行:

    @{ if(ViewContext.FormContext == null) {ViewContext.FormContext = new FormContext(); }}
    

    然后,您需要确保在每次添加/删除项目时动态重新绑定不显眼的验证:

    $("#form").removeData("validator");
    $("#form").removeData("unobtrusiveValidation");
    $.validator.unobtrusive.parse("#form");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-21
      • 2011-03-01
      • 2013-09-18
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 2014-12-04
      相关资源
      最近更新 更多