How to specify error order in data annotation in Html.ValidationSummary

I show errors in my form with

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

My domain object is inherited from the base class, and I find that the data annotation properties of the base class are displayed at the bottom of the list. This is contrary to the order in which they appear in my form.

Is there a way to indicate in which order the errors should be displayed?

Example:

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

My form (strongly typed class view):

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

Validation errors are displayed as:

 The BProperty is required. The AProperty is required. 
+3
source share
4 answers

Nope. Reflection is used to retrieve all DataAnnotations, and they are always displayed in the order in which the properties appear with a call to typeof(MagicSocks).GetTYpe().GetProperties() . In your case, I’m sure that the properties of the derived class will always appear before the properties of the base type.

You need to write your own helper and our own attributes to display validation errors in the order you choose.

-1
source

I wrote an extension for this:

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

What you can use:

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

I am not sure if my answer is right or wrong, you can try this.

  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
source

Try this filter attribute, which orders the state of the model according to the keys of the request form.

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

Use the following code to add a filter to all Actions: filters.Add(new OrderedModelStateAttribute());

0
source

Source: https://habr.com/ru/post/1333477/


All Articles