在ValidationSummary中,为什么消息的显示顺序与向ModelState添加错误的顺序不同,以及如何解决此问题?
答案 0 :(得分: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>
这可能会有所帮助..
答案 1 :(得分:2)
我遇到了这个问题,为了快速解决这个问题,我重新创建了上面的验证摘要,并使用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>
}
答案 2 :(得分:1)
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中值的顺序是未指定
强调我的。
答案 3 :(得分:1)
ValidationSummary是如此简单,如上所述它只有2个循环(您可以使用LINQ的SelectMany在1中完成),因此您可以为此创建自己的局部视图,并在5分钟内将其置于主布局中。
鉴于ValidationSummary不会在ModelState中显示Exceptions,无论如何都有充分的理由这样做。
如果你想在视图中拥有与控件相同的顺序,你可以执行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#代码文件中,这样就不会弄乱你的视图。
答案 4 :(得分:0)
除了以前的答案,您还可以使用FluentValidation框架而不是数据注释。如果要避免使用ModelState
并手动创建验证器,那么ValidationResult
对象将包含相同顺序的错误,因为在验证器构造函数中添加了相应的规则。
此外,如果启用了客户端验证 - 错误消息的顺序是相同的,作为由HtmlHelper
生成的适当输入的顺序(可能,相同的行为应该是数据注释生成的输入)。 / p>
有关详细信息,请查看here。