2009-11-29 47 views
4

我試圖找出驗證單頁結帳的最佳方法。 它包含:地址字段的自定義ASP.NET MVC驗證摘要

  • 船地址
  • 帳單地址

Address類明顯包含First NameLast NameStreet1Street2CityStateZipPhone等。

比方說,用戶在輸入任何內容之前點擊「確定」 - 然後最終出現十幾個驗證錯誤,給你一大塊看起來很醜的紅色文本。

我想驗證的地址作爲一個單一的實體,並給出一個智能錯誤 - 在適當的時候,例如「不完整的地址」,或更具體的錯誤。但我仍然希望能夠突出顯示每個有問題的單個領域。我現在看不到一個簡單的方法,因爲顯然Html.ValidationSummary幫手會顯示每個字段。

所以我想說明的總結爲:紅色ZipCity

"Your shipping address is incomplete" 

和亮點。

我想我必須做一個完全自定義的ValidationSummary,甚至可能是一個完全自定義的數據結構。

做任何驗證框架都容易這樣的總結做,在總結應該表現出一種智能總結並不僅僅是每一個人領域的錯誤。


編輯:MVC 2 RC現在支持模型級的錯誤。

ValidationSummary now supports overloads where only model-level errors are displayed. This is useful if you are displaying validation messages inline next to each form field. Previously, these messages would be duplicated in the validation summary. With these new changes, you can have the summary display an overall validation message (ex. 「There were errors in your form submission」) as well as a list of validation messages which don’t apply to a specific field.

任何人有如何做到這一點的實際樣本?

回答

1

IDataErrorInfo的有兩個成員:

  • 錯誤 - 獲取指示什麼是錯的這個對象的錯誤消息。
  • 項目 - 獲取給定名稱的屬性的錯誤消息。

如果實現錯誤會員,你將有一個錯誤消息。

+0

但隨後各個字段不會突出顯示。我不想失去視覺提示 - 尤其是因爲並非所有的字段實際都是必需的(比如Address2) – 2009-11-29 19:30:46

+0

@Simon:如果你想讓字段突出顯示,你可以添加空的錯誤:if(String.IsNullOrEmpty(address.Zip ))ModelState.AddModelError(「Zip」,「」);'它不會顯示在驗證摘要中。 – LukLed 2009-11-29 20:32:40

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一樣。

在裏面你可以檢查任何特殊和獨特的要求。 希望它有助於。

+0

你有沒有做我說的分組?我想我可以犯錯誤,我不想在錯誤信息中只顯示「*」,並在列表中過濾掉這些錯誤 – 2009-11-29 19:31:58

+0

我沒有發佈完整的代碼,因爲它的專有源代碼,但在你可以檢查的foreach在這種情況下,請檢查此屬性Street1,Street2,City,State是否全部爲空,然後跳過它們的特定消息,然後只發送一個,而不是像「您的送貨地址不完整」那樣,您仍然可以突出顯示每個單獨的字段,因爲modelState仍然具有錯誤的特定項目,但消息顯示僅爲一個。 – JOBG 2009-11-30 00:05:34

+0

我承認這就像快速,不可維護和骯髒的方式,但如果你處於急流狀態,它就會正常工作=)。 如果時間不是問題,請查看IDataErrorInfo。 – JOBG 2009-11-30 00:22:06

1

這裏是我會做什麼:

把你的驗證錯誤到的ModelState無論怎樣是最舒服的給你。您可以直接將它們添加到控制器的ModelState中,使用IDataErrorInfo或DataAnnotations和驗證運行器。只要您填充模型狀態並重新顯示視圖,它並不重要。

然後,確保所有的輸入也有相應的Html.ValidationMessage()與他們在你的表單關聯:

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

根據驗證錯誤類,這將打開你的文本的CSS規則框紅色並在旁邊顯示一個紅色星號,告訴用戶他們需要糾正他們的輸入。

最後,由於您在顯示完整驗證摘要時不感興趣,只需進行一次簡單檢查,看看ModelState是否有效,並且不顯示通用消息。

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

該解決方案將突出顯示用戶已填寫不正確的特定領域,像你想顯示錯誤的簡短說明。

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) 
     { 
      ... 
     } 
    } 
} 
+0

之前沒有查看過ValidationAttribute。謝謝 - http://msdn.microsoft.com/zh-cn/library/system.componentmodel.dataannotations.validationattribute.aspx – 2009-12-29 09:52:08

+0

擁有一個專用的Address類可能會帶來額外的好處。例如,您可以覆蓋ToString()或在其上放置Format()方法以在確認過程中顯示地址。此外,它可用於BillTo地址字段。希望能幫助到你! – 2009-12-29 16:33:44

+0

奇怪 - 它不會讓我接受你的答案(或任何這些) – 2010-04-15 00:00:25

0

Scottgu剛剛發佈了great blog post on the new validation features

雖然它不會進入深度如何實現模型級驗證它指向的默認ASP.NET MVC 2應用項目模板中如何做到這一點的解釋:

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).