地址字段的自定义ASP.NET MVC验证摘要

时间:2009-11-29 08:31:01

标签: asp.net-mvc validation idataerrorinfo

我正在尝试找出验证单页结帐的最佳方法。 它包含:

  • 发货地址
  • 帐单邮寄地址

明确的地址类包含First NameLast NameStreet1Street2CityStateZipPhone等。

让我们说用户在输入任何内容之前点击“确定” - 然后你会得到十几个或更多验证错误,这会给你一大块看起来很丑的红色文字。

我想将地址验证为单个实体,并在适当时给出智能错误 - 例如“不完整地址”或更具体的错误。但我仍然希望能够突出显示有问题的每个字段。我现在无法看到一种简单的方法,因为显然Html.ValidationSummary助手会显示每个字段。

所以我想把摘要显示为:

 "Your shipping address is incomplete"

并以红色ZipCity突出显示。

我想我必须做一个完全自定义的ValidationSummary,甚至可能是一个完全自定义的数据结构。

任何验证框架都可以使这样的摘要更容易,摘要应该显示智能摘要,而不仅仅是每个字段错误。


修改:MVC 2 RC现在支持模型级错误。

  

ValidationSummary现在支持   只有模型级别的重载   显示错误。这很有用   如果您正在显示验证   每个表单旁边的内联邮件   领域。以前,这些消息   将在验证中重复   摘要。有了这些新的变化,你   可以有摘要显示   整体验证信息(例如“那里   您的表单提交中的错误“)   以及验证列表   不适用于的消息   特定领域。

有人得到了如何做到这一点的实际样本吗?

5 个答案:

答案 0 :(得分:3)

您可以使用复合Address属性并将整个地址作为一个单元进行验证:

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
    public string Zip { get; set; }
}

public class Order
{
    [Required]
    public string FirstName { get; set; }

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

    [AddressRequired("Your shipping address is incomplete")]
    public Address ShipTo { get; set; }

    [AddressRequired("Your billing address is incomplete")]
    public Address BillTo { get; set; }

    // you could do this if you still need 1:1 mapping for model binding
    public string ShippingCity
    {
        get { return ShipTo.City; }
        set { ShipTo.City = value; }
    }
}

验证属性看起来像这样:

public class AddressRequiredAttribute : ValidationAttribute
{
    ...

    public override bool IsValid(object value)
    {
        var address = value as Address;

        if (address != null)
        {
            ...
        }
    }
}

答案 1 :(得分:1)

IDataErrorInfo有两个成员:

  • 错误 - 获取一条错误消息,指出此对象出了什么问题。
  • Item - 获取具有给定名称的属性的错误消息。

如果您实施了错误成员,则会收到一条错误消息。

答案 2 :(得分:1)

我在最近的一个项目中处理类似的问题,我做了一个自定义的验证摘要,这里是代码:

<%
      if (!ViewData.ModelState.IsValid)
       {
           Response.Write("<div class=\"prepend-1 span-10 last notice\">");
           Response.Write("<span>Please fix fields marked with an asteristk <span class=\"ss_sprite ss_asterisk_orange\"> </span></span>");
           Response.Write("<ul>");
           foreach (KeyValuePair<string, ModelState> keyValuePair in ViewData.ModelState)
           {
               foreach (ModelError modelError in keyValuePair.Value.Errors)
               {
                %>
                <li><%= Html.Encode(modelError.ErrorMessage)%></li>
                <%
       }
           } Response.Write("</ul>");
           Response.Write("</div>");
       }
    %> 

我是在Partial View中完成的,但也许最好将它包装在HTML Helper方法中,就像原始的ValidationSummary一样。

您可以在里面查看任何特殊和独特的要求。 希望它有所帮助。

答案 3 :(得分:1)

以下是我要做的事情:

将您的验证错误放入ModelState中,无论哪种方式最适合您。您可以使用IDataErrorInfo或DataAnnotations和验证运行器将它们直接添加到控制器中的ModelState。只要您使用错误填充ModelState并重新显示视图就没有关系。

然后,确保您的所有输入在表单中都有相应的Html.ValidationMessage():

<%= Html.TextBox("city") %>
<%= Html.ValidationMessage("city", "*") %>

根据验证错误类的css规则,这会将文本框变为红色并在其旁边显示一个红色星号,告诉用户他们需要更正输入。

最后,由于您没有兴趣显示完整的验证摘要,只需进行简单的检查,看看ModelState是否有效,如果没有显示您的通用消息。

<% if (!ViewData.ModelState.IsValid) { %>
    <div id="validation-message">Your Shipping Address in Incomplete</div>
<% } %>

此解决方案将突出显示用户错误填写的特定字段,并显示错误的简短描述。

答案 4 :(得分:0)

Scottgu刚刚发布了great blog post on the new validation features

虽然它没有深入探讨如何实现模型级验证,但它指向默认的ASP.NET MVC 2应用程序项目模板,作为如何执行此操作的说明:

  

除了创建验证   适用于个人的属性   对象的属性,你也可以   应用验证属性   班级 - 允许你这样做   执行验证逻辑   对象中的多个属性。   有关这方面的一个例子,你   可以复习一下   “PropertiesMustMatchAttribute”自定义   包含在中的属性   AccountModels.cs / vb文件内   默认的ASP.NET MVC 2应用程序   项目模板(只做一个文件 - &gt;新   VS中的ASP.NET MVC 2 Web项目   2010年,寻找这个课程。)