Stop Html.ValidationSummary() from changing the order of validation messages

跟風遠走 提交于 2019-12-06 12:04:24

问题


In a ValidationSummary, why are the messages shown in a different order than the order you added errors to the ModelState and how might I fix this?


回答1:


asp.net mvc is open source so you can see the code for ValidationSummary directly.

http://www.asp.net/mvc/download/

That said, I'm pretty sure ModelState is a dictionary. So if ValidationSummary is iterating over the key/values in the ModelState dictionary looking for errors the order is going to be random.


I downloaded the code at work. From ValidationSummary in MVC/Html/ValidationExtensions.cs:

foreach (ModelState modelState in htmlHelper.ViewData.ModelState.Values) {
    foreach (ModelError modelError in modelState.Errors) {
        // stuff to build a string with the error
    }
}

So it is iterating over the values in the dictionary. And from MSDN:

For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair(TKey, TValue) structure representing a value and its key. The order in which the items are returned is undefined.

and

The order of the values in the Dictionary(TKey, TValue).ValueCollection is unspecified

Emphasis mine.




回答2:


<ul class="validation-summary-errors">
<%

       foreach (ModelState modelState in (ViewContext.ViewData.ModelState.Values)){
        foreach (ModelError modelError in modelState.Errors) {
            // stuff to build a string with the error
                %>
                <li><%=modelError.ErrorMessage %></li>
                <%   
        }
    }
%>
</ul>

This might be helpful..




回答3:


I had this problem, and to solve it quickly I recreated the validation summary like above and used ViewBag to store the errors in the correct order by referencing an array of ordered field names. Not particularly nice but the fastest thing I could think of at the time. Razor/MVC3.

Controller code:

    List<string> fieldOrder = new List<string>(new string[] { 
"Firstname", "Surname", "Telephone", "Mobile", "EmailAddress", "AddressLine1", "AddressLine2", "TownCity", "County" })
.Select(f => f.ToLower()).ToList();

    ViewBag.SortedErrors = ModelState
       .Select(m => new { Order = fieldOrder.IndexOf(m.Key.ToLower()), Error = m.Value})
       .OrderBy(m => m.Order)
       .SelectMany(m => m.Error.Errors.Select(e => e.ErrorMessage))
       .ToArray();

Then in the view:

@if (!ViewData.ModelState.IsValid)
{
    <div class="validation-summary-errors">  
    <ul>
        @foreach (string sortedError in ViewBag.SortedErrors)
        {
            <li>@sortedError</li> 
        }
    </ul>
    </div>
}



回答4:


ValidationSummary is so simple, as pointed above it is just 2 loops (which you can do in 1 with LINQ's SelectMany) so you can make your own partial view for this and place it in master layout in 5 minutes.

And given that ValidationSummary will not display Exceptions put in ModelState, there's a good reason to do this, anyway.

If you want to have the same order as controls in your view, you can do jQuery:

var list = {};
<% foreach (var error in ModelState)
{%>
  list['<%=error.Key%>'] = '<%=error.Value.Message%>';
<%}%>
$(*[name]).each(function(i,o){
  isError = list.indexOf(o.name) >= 0;
  if (isError)
     $(".validationSummary").append("<li>" + list[o.name] + "</li>");
});

Well, this code is from my head so it's pseudo... but this is the idea. Basically you iterate over all elements with name attribute, and check ModelState for and error. To make this happen, your server-side code creates a client-side dictionary of errors.

A better one would be to write a HtmlHelper extension that basically does the same, but in C# code file so that it doesn't mess your view.




回答5:


In addition to previous answers, you can use FluentValidation framework instead of Data Annotations. If to avoid using ModelState and create validator manually, then ValidationResult object will contain errors in same order, as according rules were added in validator constructor.

Additionally, if client-side validation enabled — order of error messages is the same, as order of appropriate inputs, which generated by HtmlHelper (probably, the same behavior should be for Data Annotations generated inputs).

For more information look here.



来源:https://stackoverflow.com/questions/1463754/stop-html-validationsummary-from-changing-the-order-of-validation-messages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!