2010-10-12 8 views
3

Je l'affichage des erreurs sur mon formulaire avec l'utilisation deComment spécifier l'ordre d'erreurs d'annotation de données dans Html.ValidationSummary

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

Mon objet de domaine hérite d'une classe de base et je trouve que la classe de base Les propriétés d'annotation de données sont affichées en bas de la liste. Cela va à l'encontre de l'ordre dans lequel ils apparaissent dans mon formulaire.

Existe-t-il un moyen de spécifier dans quel ordre les erreurs doivent être affichées?

Exemple:

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

Ma forme (vue fortement typée de ClassB):

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

erreurs de validation apparaissent comme:

The BProperty is required. 
The AProperty is required. 

Répondre

-1

Non. La réflexion est utilisée pour obtenir toutes les DataAnnotations et elles apparaissent toujours dans l'ordre où les propriétés apparaîtraient avec un appel à typeof(MagicSocks).GetTYpe().GetProperties(). Dans votre cas, je suis assez sûr que les propriétés de classe dérivées apparaîtront toujours avant les propriétés de type de base.

Vous devez écrire votre propre aide et nos propres attributs pour afficher les erreurs de validation dans l'ordre que vous choisissez.

+0

Où peut-on écrire une aide pour déterminer l'ordre? La seule chose que je peux trouver dans System.ComponentModel est la classe PropertyChangedEventManager, mais je ne pense pas que ce soit la façon de le faire. –

+0

Lorsque j'exécute cet exemple de code sur mon modèle d'édition (qui n'a pas de parents), j'obtiens un tableau PropertyInfo avec des éléments comme System.String Name mais pas de méthodes publiques. – empty

0

Je ne suis pas sûr que ma réponse soit bonne ou mauvaise, vous pouvez essayer de cette façon.

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 

    } 
+0

Merci, mais je cherchais à voir si quelqu'un avait trouvé une solution plus élégante avec une sorte de commande plutôt que de simplement se fier à l'ordre alphabétique. – David

1

J'ai écrit une extension pour cela:

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); 
} 

que vous pouvez utiliser par:

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

Pour plus d'informations sur les méthodes d'extension, voir http://msdn.microsoft.com/fr-fr/library/bb383977.aspx – empty

0

Essayez cet attribut de filtre qui commande l'état du modèle en fonction de la forme de la demande clés.

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) 
     { 
     } 
    } 
} 

Utilisez le code suivant pour ajouter le filtre à toutes les actions: filters.Add(new OrderedModelStateAttribute());