ValidationSummary で、ModelState にエラーを追加した順序とは異なる順序でメッセージが表示されるのはなぜですか? これを修正するにはどうすればよいですか?
5 に答える
<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>
これは役に立つかもしれません。
私はこの問題を抱えていました。それをすばやく解決するために、上記のように検証の概要を再作成し、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>
}
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 の値の順序は指定されていません
鉱山を強調します。
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# コード ファイルで記述します。