客户端验证mvc 3.0中动态生成的表单元素

时间:2011-07-29 06:58:07

标签: jquery asp.net-mvc-3 client-side

我已经阅读了很多关于如何在mvc 3.0中验证动态生成内容的内容,例如xhalent已编写的内容 ,但我无法理解如何在我的代码中使用它。我的意思是它不适用于动态生成的表单元素。 这是我的Model类:

 public class Person
{
    [Required]
    public string Name { get; set; }

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

    public IList<Address> Addresses{get;set;}

    public Person()
    {
        Addresses = new List<Address>()
                            {
                                new Address(){Street="1"},new Address(){Street="2"}
                            };
    }


}

public class Address
{
    [Required(ErrorMessage="Error")]
    public string Street { get; set; }
}

这是开始显示表单的视图:

<script src="<%: Url.Content("~/Scripts/jquery-1.5.1.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.min.js") %>" type="text/javascript"></script>
<script src="<%: Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js") %>"
    type="text/javascript"></script>

<% using (Html.BeginForm())
       { %>
    <%: Html.ValidationSummary(true) %>
    <fieldset>
        <legend>Person</legend>
        <%: Html.EditorForModel() %>
            <div class="phone-numbers">
                <%
           foreach (var item in Model.Addresses)
       {

            %>
            <%Html.RenderPartial("EditorTemplates/Addresses", item);%>
            <%} %>
        </div>

    <div style="padding: 10px 0px 10px 0px">
        <a id="add-phone" href="javascript:void(0);">Add another</a>
    </div>
    <input type="submit" value="Create" />
</fieldset>
<% } %>
</div>

  $().ready(function () {
             $("#add-phone").click(function () {
                 $.ajax({
                     url: '<%: Url.Action("GetNewAddress") %>',
                     success: function (data) {
                         $(".phone-numbers").append(data);                   
                    }
                });
            });
        });

这是地址的部分视图:

<div style="padding: 5px 0px 5px 0px" name="editorRow" id="editorRow">
        <%: Html.LabelFor(m => m.Street) %>
        <%: Html.EditorFor(m => m.Street)%>
        <%:Html.ValidationMessageFor(m=>m.Street) %>
    </div>

1 个答案:

答案 0 :(得分:4)

首先,如果是部分视图,请在顶部添加

<%
 if (Html.ViewContext.FormContext == null)
    {
        Html.ViewContext.FormContext = new FormContext();
    }
%>

这应该为生成的内容添加不显眼的data-val- *验证属性。在您的ajax下载的成功功能中,在末尾插入this

 $().ready(function () {
             $("#add-phone").click(function () {
                 $.ajax({
                     url: '<%: Url.Action("GetNewAddress") %>',
                     success: function (data) {
                         $(".phone-numbers").append(data);      

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

                    }
                });
            });
        });

这次它应该自动解析下载的内容并对其应用验证

我看了一下你的项目,发现动态验证不起作用的原因。实际上你在那里遇到的问题多于验证。首先,用于渲染地址的技术不正确。这样,您生成的所有输入都具有相同的ID和名称值。这就是为什么验证器无法区分动态添加内容和前一个内容的原因,它认为所有输入都是相同的,并根据第一条街道验证所有街道。而且,如果您发布了要在服务器上创建的内容,那么asp.net mvc模型绑定器就无法绑定街道数组 - 原因与验证器无法工作的原因相同。请查看this文章,以便在客户端正确生成列表内容。对于以后的动态注入,您可以更改控制器代码,如

public ActionResult GetNewAddress(string id)
        {
            ViewData.TemplateInfo.HtmlFieldPrefix = string.Format("[{0}]", id);
            return View("EditorTemplates/Addresses", new Address());
        }

从客户端传递正确的ID取决于你:)。

此外,您没有正确使用EditorTemplates,它们应与Html.DisplayFor()一起使用,您不必手动指定其名称。更多地了解它们,网上有数十篇文章