阻止 Html.ValidationSummary() 更改验证消息的顺序

发布于 2024-08-05 17:18:47 字数 75 浏览 6 评论 0原文

在 ValidationSummary 中,为什么消息显示的顺序与您向 ModelState 添加错误的顺序不同?我该如何解决这个问题?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

空气里的味道 2024-08-12 17:18:47
<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>

这可能会有所帮助..

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

今天小雨转甜 2024-08-12 17:18:47

我遇到了这个问题,为了快速解决它,我重新创建了上面的验证摘要,并使用 ViewBag 通过引用有序字段名称数组以正确的顺序存储错误。不是特别好,但是是我当时能想到的最快的事情。剃刀/MVC3。

控制器代码:

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

然后在视图中:

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

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>
}
南渊 2024-08-12 17:18:47

asp.net mvc 是开源的,因此您可以直接查看 ValidationSummary 的代码。

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

也就是说,我'我很确定 ModelState 是一本字典。因此,如果 ValidationSummary 迭代 ModelState 字典中的键/值以查找错误,则顺序将是随机的。


我在工作时下载了代码。来自 MVC/Html/ValidationExtensions.cs 中的 ValidationSummary:

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

因此它正在迭代字典中的值。来自 MSDN:

出于枚举的目的,字典中的每个项目都被视为表示值及其键的 KeyValuePair(TKey, TValue) 结构。 退回物品的顺序未定义。

并且

Dictionary(TKey, TValue).ValueCollection 中值的顺序未指定

强调我的。

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.

萝莉病 2024-08-12 17:18:47

ValidationSummary 非常简单,如上所述,它只有 2 个循环(您可以使用 LINQ 的 SelectMany 在 1 个循环中完成),因此您可以为此创建自己的部分视图,并在 5 分钟内将其放置在主布局中。

鉴于 ValidationSummary 不会显示放入 ModelState 中的异常,无论如何,有充分的理由这样做。

如果你想在视图中拥有与控件相同的顺序,你可以使用 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>");
});

嗯,这段代码来自我的头脑,所以它是伪的......但这就是想法。基本上,您可以迭代具有 name 属性的所有元素,并检查 ModelState 是否有错误。为了实现这一点,您的服务器端代码会创建一个客户端错误字典。

更好的方法是编写一个基本上具有相同功能的 HtmlHelper 扩展,但在 C# 代码文件中,这样就不会扰乱您的视图。

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.

來不及說愛妳 2024-08-12 17:18:47

除了前面的答案之外,您还可以使用 FluentValidation 框架代替数据注释。如果要避免使用 ModelState 并手动创建验证器,则 ValidationResult 对象将包含相同顺序的错误,因为在验证器构造函数中添加了相应的规则。

此外,如果启用了客户端验证 - 错误消息的顺序与由 HtmlHelper 生成的适当输入的顺序相同(可能数据注释生成的输入应该具有相同的行为)。

如需了解更多信息,请查看此处

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文