4

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

  • 收货地址
  • 帐单地址
  • 等等

Address 类明显包含First Name, Last Name, Street1, Street2, City, State,ZipPhone

假设用户在输入任何内容之前单击“确定” - 然后您最终会遇到十几个或更多验证错误,给您一大块看起来很难看的红色文本。

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

所以我想将摘要显示为:

 "Your shipping address is incomplete"

并以红色Zip和突出显示City

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

是否有任何验证框架使这样的摘要更容易进行,摘要应该显示智能摘要,而不仅仅是每个单独的字段错误。


编辑:MVC 2 RC现在支持模型级错误。

ValidationSummary 现在支持仅显示模型级错误的重载。如果您在每个表单字段旁边内嵌显示验证消息,这很有用。以前,这些消息将在验证摘要中重复。通过这些新更改,您可以让摘要显示整体验证消息(例如“您的表单提交中有错误”)以及不适用于特定字段的验证消息列表。

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

4

5 回答 5

3

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

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)
        {
            ...
        }
    }
}
于 2009-12-29T05:37:26.433 回答
1

IDataErrorInfo 有两个成员:

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

如果您实现 Error 成员,您将收到一条错误消息。

于 2009-11-29T15:10:33.193 回答
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>
<% } %>

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

于 2009-12-25T14:08:53.987 回答
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>");
       }
    %> 

我是在部分视图中完成的,但最好将其包装在 HTML Helper 方法中,就像原始的 ValidationSummary 一样。

在里面,您可以检查任何特殊和独特的要求。希望能帮助到你。

于 2009-11-29T15:30:04.643 回答
0

Scottgu just released a great blog post on the new validation features.

While it doesn't go into depth on how to implement model-level validation it points to the default ASP.NET MVC 2 application project template as an explanation of how to do this:

In addition to creating validation attributes that apply to individual properties on an object, you can also apply validation attributes at the class level – which allows you to perform validation logic across multiple properties within an object. For an example of this in action, you can review the “PropertiesMustMatchAttribute” custom attribute that is included in the AccountModels.cs/vb file within the default ASP.NET MVC 2 application project template (just do a File->New ASP.NET MVC 2 Web Project within VS 2010 and look for this class).

于 2010-01-17T05:58:38.643 回答