web-dev-qa-db-ja.com

カスタムValidationSummaryテンプレートAsp.net MVC 3

Asp.Net MVC3でプロジェクトに取り組んでいます

ビューには@Html.ValidationSummary(true)があり、通常のように生成されます

<div class="validation-summary-errors">
    <ul>
        <li>Something bad Happened!</li>
    </ul>
</div>

このValidationSummaryをMyValidationSummaryに拡張し、次のようなHTMLコードテンプレートを生成するにはどうすればよいですか。

<div class="notification warning"> 
    <span></span> 
    <div class="text"> <p>Something bad Happened!</p> </div> 
</div>
62
Dynamikus

この question は、カスタム検証の概要を記述する手順を詳しく説明しています。

[〜#〜] edit [〜#〜]これはあなたが望むことをするでしょう:

public static class LinqExt 
{
    public static string MyValidationSummary(this HtmlHelper helper, string validationMessage="")
    {
        string retVal = "";
        if (helper.ViewData.ModelState.IsValid)
            return "";

        retVal += "<div class='notification-warnings'><span>";
        if (!String.IsNullOrEmpty(validationMessage))
            retVal += helper.Encode(validationMessage);
        retVal += "</span>";
        retVal += "<div class='text'>";
        foreach (var key in helper.ViewData.ModelState.Keys) 
        {
            foreach(var err in helper.ViewData.ModelState[key].Errors)
                retVal += "<p>" + helper.Encode(err.ErrorMessage) + "</p>";
        }
        retVal += "</div></div>";
        return retVal.ToString();
    }
}

コードは自明です。 modelstateエラーを列挙し、選択したdom要素でエラーをラップするだけです。次のように使用するとエラーが発生します。

<%:Html.MyValidationSummary()%>

ページ上にHTMLタグを表示するのではなく、テキストとして表示します。

<%=Html.MyValidationSummary()%>

これは正常に機能します。

46

私のアプローチは、カスタムValidationSummary.cshtml

@model ModelStateDictionary

@if(!Model.IsValid)
{
    <div class="validation-summary-errors">
        <ul>
            @foreach (var modelError in 
                     Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
            {
                <li>@modelError.ErrorMessage</li>
            }
        </ul>
    </div>
}

この部分ビューを共有フォルダーに入れ、コードから参照します。

@Html.Partial("_ValidationSummary", ViewData.ModelState);

このようにして、htmlを完全に制御できます。

134
flo scheiwiller

flos's answer に基づいて、MicrosoftのjQuery Unobtrusive Validationと互換性を持たせ、Bootstrapの3つのパネルスタイルを追加しました。新しいコードは次のとおりです。

@model ModelStateDictionary

<div class="@(Html.ViewData.ModelState.IsValid ? "validation-summary-valid" : "validation-summary-errors") panel panel-danger"
     data-valmsg-summary="true">
    <div class="panel-heading">
        Please, correct the following errors:
    </div>
    <div class="panel-body">
        <ul>
            @foreach(var modelError in Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
            {
                <li>@modelError.ErrorMessage</li>
            }
        </ul>
    </div>
</div>

詳細については、こちらをご覧ください。

Bootstrap 3 panel でスタイル設定されたカスタムASP.NET MVC @ Html.ValidationSummaryの作成

また、このカスタムValidationSummaryの動作を示すサンプルASP.NET MVCプロジェクトも作成しました。ここで入手してください:

https://github.com/leniel/AspNetMvcCustomHtmlValidationSummary

23

私の答えがここに投稿されているだけです。

MvcHtmlStringを取り、それをHTMLにデコードする単純な拡張メソッドを使用します。

    public static MvcHtmlString ToMvcHtmlString(this MvcHtmlString htmlString)
    {
        if (htmlString != null)
        {
            return new MvcHtmlString(HttpUtility.HtmlDecode(htmlString.ToString()));
        }
        return null;
    }

これを組み込むために、次のように検証サマリーヘルパーをchstmlに追加します。

@Html.ValidationSummary(true).ToMvcHtmlString()

つまり、検証サマリーにカスタムHTMLを追加できます。

ModelState.AddModelError("", "<p>This message can have html in it</p>");

また、フィールド検証メッセージにカスタムHTMLを追加することもできます。

ModelState.AddModelError("MyField", "<p>This message can have html in it</p>");

また、フィールド検証メッセージをHTMLで動作させるには:

@Html.ValidationMessageFor(model => model.MyField).ToMvcHtmlString();
2
Matt Roberts

関連スタイルの追加:

.field-validation-error {
    color: #b94a48;
}

.field-validation-valid {
    display: none;
}

input.input-validation-error {
    border: 1px solid #b94a48;
}

input[type="checkbox"].input-validation-error {
    border: 0 none;
}

.validation-summary-errors {
    color: #b94a48;
}

.validation-summary-valid {
    display: none;
}
1
Yovav

サーバー側の検証(ファイルの内容の確認など)のためだけに似たようなことをしなければならず、@ Html.ValidationSummaryを完全に奪い取ってしまいました。

Controllerを拡張するBaseControllerクラスがあり、内部でいくつかの目的でOnActionExecutingメソッドをオーバーライドします。エラーメッセージ用にViewBagで新しいリストを作成し、アクションを実行する前にリストが初期化されていることを確認します。次に、表示するエラーを追加して、画面に表示できます。

この質問の目的では、これは次のようになります。

public class BaseController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (ViewBag.ErrorsList == null)
        {
            ViewBag.ErrorsList = new List<string>();
        }
    }
}

次に、_Layout.cshtmlで@RenderBody()の上に以下を追加します

@if(ViewBag.ErrorsList.Count > 0)
{
    <div class="container margin-top-10 alert alert-danger">
        <h3><i class="glyphicon glyphicon-warning-sign"></i></h3><br/>
        @foreach (string error in @ViewBag.ErrorsList)
        {
            @error <br/>
        }
    </div>
    @RenderBody()
}

検証エラーメッセージとして表示するサーバー側でエラーが発生するたびに、ViewBag.ErrorsListに追加します。

ViewBag.ErrorsList.Add("Something bad happened...");

出来上がり、ValitationSummaryと同じ方法でエラーが渡される、任意のスタイルのサーバー側検証エラーメッセージ用の1つのカスタムコンテナ。

1
Dean Puckett

トップレベルのメッセージだけを表示したいと思いました。下のフィールドの横にはすでに検証があります。 @ Leniel-Macaferiのソリューションに取り組むことで、jQuery検証で動作するようになりました。(style = "display:none;"を追加しました)

<div class="@(Html.ViewData.ModelState.IsValid ? "validation-summary-valid" : "validation-summary-errors")"
     data-valmsg-summary="true">
    <div>
        There are still some fields not filled in before we can submit this. Please correct.
    </div>
    <div style="display: none;">
        <ul>
            @foreach (var modelError in Model.SelectMany(keyValuePair => keyValuePair.Value.Errors))
            {
                <li>@modelError.ErrorMessage</li>
            }
        </ul>
    </div>
</div>
0
Robert Koch