1

知りたいのですが、モデルのフィールドの検証からオブジェクト(たとえばメッセージインスタンス)を渡し、ModelState(または他の何かを使用して)インスタンスからそれらを取得する方法はありますか?これを求めているのは、検証エラーメッセージの種類を区別して、一度に必要なメッセージのみをビューに表示できるようにするためです。(例:一意の検証メッセージの前に表示される必須メッセージ。)

カスタム作成されたMessageオブジェクトを使用しようとしていましたが、messageTypeフィールドを使用して区別できます。ただし、検証では文字列メッセージのみが返されるため、方法を考えることはできません。

4

1 に答える 1

2

ModelState からメッセージを読み取り、メッセージの内容に基づいてタイプを決定しても問題ありませんか? すべての検証にカスタム メッセージを設定すると、これを行うことができます。

次に、特定のコンテンツを探して各メッセージを評価し、アクションを実行できます。Required属性とInfo残りに「エラー」という単語を入れるなど。

テストに使用できるクラスは次のとおりです

モデル


public class EmployeeViewModel {

    public int ID { get; set; }

    [Display(Name = "First Name")]
    [Required(ErrorMessage = "Error")]
    public string FirstName { get; set; }

    [Display(Name = "Last Name")]
    [Required(ErrorMessage = "Error")]
    public string LastName { get; set; }

    [Display(Name = "Username")]
    public string Username { get; set; }

    [Display(Name = "Email Address")]
    public string EmailAddress { get; set; }
}

コントローラ


using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using TestApp.Models;

namespace TestApp.Controllers {

    public class HomeController : Controller {

        public ActionResult Index() {
            return RedirectToAction("Test");
        }

        public ActionResult Test() {
            var model = new EmployeeViewModel();
            return View(model);
        }

        [HttpPost]
        public ActionResult Test(EmployeeViewModel model) {
            // Force an error on this property - THIS should be the only real error that gets returned back to the view
            ModelState.AddModelError("", "Error on First Name");

            if(model.EmailAddress == null) // Add an INFO message
                ModelState.AddModelError("", "Email Address Info");
            if (model.Username == null) // Add another INFO message
                ModelState.AddModelError("", "Username Info");

            // Get the Real error off the ModelState
            var errors = GetRealErrors(ModelState);

            // clear out anything that the ModelState currently has in it's Errors collection
            foreach (var modelValue in ModelState.Values) {
                modelValue.Errors.Clear();
            }
            // Add the real errors back on to the ModelState
            foreach (var realError in errors) {
                ModelState.AddModelError("", realError.ErrorMessage);
            }
            return View(model);
        }

        private IEnumerable<ModelError> GetRealErrors(IEnumerable<KeyValuePair<string, ModelState>> modelStateDictionary) {
            var errorMessages = new List<ModelError>() ;
            foreach (var keyValuePair in modelStateDictionary.Where(keyValuePair => keyValuePair.Value.Errors.Count > 0)) {
                errorMessages.AddRange(keyValuePair.Value.Errors.Where(error => !error.ErrorMessage.Contains("Info")));
            }
            return errorMessages;
        }
    }
}

private IEnumerable<ModelError> GetRealErrors(IEnumerable<KeyValuePair<string, ModelState>> modelStateDictionary) {
    var errorMessages = new List<ModelError>() ;
    foreach (var keyValuePair in modelStateDictionary.Where(keyValuePair => keyValuePair.Value.Errors.Count > 0)) {
        errorMessages.AddRange(keyValuePair.Value.Errors.Where(error => !error.ErrorMessage.Contains("Info")));
    }
    return errorMessages;
}

意見


@model TestApp.Models.EmployeeViewModel

<h2>Test</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>EmployeeViewModel</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Username)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Username)
            @Html.ValidationMessageFor(model => model.Username)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.EmailAddress)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.EmailAddress)
            @Html.ValidationMessageFor(model => model.EmailAddress)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
于 2012-06-06T01:43:09.563 に答える