2010-10-12 52 views
3

我我的表格上顯示錯誤與使用如何指定數據標註錯誤的順序Html.ValidationSummary

<%= Html.ValidationSummary("Please review the errors below") %> 

我的域對象從一個基類繼承,我發現基類數據註釋屬性顯示在列表的底部。這違背了他們在我的表格中出現的順序。

有什麼方法可以指定錯誤顯示的順序嗎?

實施例:

public class ClassA { [Required]public string AProperty; } 
public class ClassB : ClassA { [Required]public string BProperty; } 

我的形式(強類型ClassB的的視圖):

AProperty: <%= Html.TextBoxFor(m => m.AProperty) %> 
BProperty: <%= Html.TextBoxFor(m => m.BProperty) %> 

驗證錯誤作爲出現:

The BProperty is required. 
The AProperty is required. 

回答

-1

不。反射用於獲取所有DataAnnotations,並且它們總是以屬性出現的順序顯示,並調用typeof(MagicSocks).GetTYpe().GetProperties()。在你的情況,我很確定派生類屬性將始終出現在基類型屬性之前。

您必須編寫您自己的幫助程序和我們自己的屬性,以按您選擇的順序顯示驗證錯誤。

+0

從哪裏會寫一個幫手來確定訂單?我在System.ComponentModel中唯一可以找到的是PropertyChangedEventManager類,但我不認爲這是實現它的方法。 – 2010-12-24 17:16:23

+0

當我在我的編輯模型(沒有父母)上運行此示例代碼時,我得到一個PropertyInfo數組,其中包含像System.String Name這樣的項目,但沒有公共方法。 – empty 2015-01-07 18:57:04

0

我不確定我的回答是對還是錯,你可以試試這種方式。根據請求的形式

ModelState.OrderByKeys(new[] { "AProperty", "BProperty" }); 
+0

謝謝,但我期待着看看有人提出了一種更優雅的解決方案,而不是僅僅依靠字母順序。 – David 2010-10-13 07:53:23

1

我寫這個的延伸:

public static void OrderByKeys(this ModelStateDictionary modelStateDictionary, IEnumerable<string> keys) 
{ 
    ModelStateDictionary result = new ModelStateDictionary(); 
    foreach (string key in keys) 
    { 
     if (modelStateDictionary.ContainsKey(key) && !result.ContainsKey(key)) 
     { 
      result.Add(key, modelStateDictionary[key]); 
     } 
    } 
    foreach (string key in modelStateDictionary.Keys) 
    { 
     if (!result.ContainsKey(key)) 
     { 
      result.Add(key, modelStateDictionary[key]); 
     } 
    } 
    modelStateDictionary.Clear(); 
    modelStateDictionary.Merge(result); 
} 

您可以通過使用鍵。

using System.Linq; 
using System.Web.Mvc; 

namespace 
{ 
    public class OrderedModelStateAttribute : FilterAttribute, IActionFilter 
    { 
     public void OnActionExecuted(ActionExecutedContext filterContext) 
     { 
      var modelState = filterContext.Controller.ViewData.ModelState; 
      var orderedModelState = new ModelStateDictionary(); 

      foreach (var key in filterContext.HttpContext.Request.Form.Keys.Cast<string>() 
              .Where(
               key => 
               modelState.ContainsKey(key) && !orderedModelState.ContainsKey(key))) 
      { 
       orderedModelState.Add(key, modelState[key]); 
      } 

      foreach (var key in modelState.Keys.Where(key => !orderedModelState.ContainsKey(key))) 
      { 
       orderedModelState.Add(key, modelState[key]); 
      } 

      modelState.Clear(); 
      modelState.Merge(orderedModelState); 
     } 

     public void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
     } 
    } 
} 

使用下面的代碼過濾器添加到所有操作: filters.Add(new OrderedModelStateAttribute());

+0

有關擴展方法的信息,請參閱http://msdn.microsoft.com/en-us/library/bb383977.aspx – empty 2015-01-07 19:32:00

0

嘗試哪些訂單模型的狀態此過濾器屬性:

public ActionResult yourAction(your params) 
    { 
      if (!ModelState.IsValid) 
      { 
       var errs = from er in tmpErrs 
          orderby er.Key 
          select er; 

       ModelState.Clear(); 

       foreach (var err in errs) 
       { 
        ModelState.Add(err); 
       } 
      } 
    // your code 

    }