2

DavidHaydenのブログや公式のASP.NetMVCチュートリアルなど、Web上の検証チュートリアルと例に従おうとしていますが、実際の検証エラーを表示するための以下のコードを取得できません。次のようなビューがある場合:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication1.Models.Parent>" %>

<%-- ... content stuff ... --%>

<%= Html.ValidationSummary("Edit was unsuccessful. Correct errors and retry.") %>
<% using (Html.BeginForm()) {%>

<%-- ... "Parent" editor form stuff... --%>

        <p>
            <label for="Age">Age:</label>
            <%= Html.TextBox("Age", Model.Age)%>
            <%= Html.ValidationMessage("Age", "*")%>
        </p>

<%-- etc... --%>

次のようなモデルクラスの場合:

public class Parent
{
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public int Age { get; set; }
    public int Id { get; set; }
}

「xxx」(非整数)などの無効なAgeを入力すると(Ageはintとして宣言されているため)、ビューに「編集に失敗しました。エラーを修正して再試行してください」というメッセージが画面の上部に正しく表示されます。 、および[年齢]テキストボックスを強調表示し、その横に赤いアスタリスクを付けて、エラーを示します。ただし、ValidationSummaryではエラーメッセージのリストは表示されません。独自の検証を行うと(たとえば、以下のLastNameの場合)、メッセージは正しく表示されますが、フィールドに不正な値がある場合、TryUpdateModelの組み込み検証ではメッセージが表示されないようです。

これが私のコントローラーコードで呼び出されるアクションです:

    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult EditParent(int id, FormCollection collection)
    {
        // Get an updated version of the Parent from the repository:
        Parent currentParent = theParentService.Read(id);

        // Exclude database "Id" from the update:
        TryUpdateModel(currentParent, null, null, new string[]{"Id"});
        if (String.IsNullOrEmpty(currentParent.LastName))
            ModelState.AddModelError("LastName", "Last name can't be empty.");
        if (!ModelState.IsValid)
            return View(currentParent);

        theParentService.Update(currentParent);
        return View(currentParent);
    }

私は何を取りこぼしたか?

4

1 に答える 1

2

Microsoft からASP.NET MVC v1.0のソース コードをダウンロードして調べたところ、偶然または設計により、少なくとも既定では、やりたいことを実行する方法がないことがわかりました。どうやら UpdateModel または TryUpdateModel の呼び出し中に、整数の検証 (たとえば) が失敗した場合、不正な値の ModelState に関連付けられた ModelError に ErrorMessage が明示的に設定されず、代わりに Exception プロパティが設定されます。MVC ValidationExtensions のコードによると、エラー テキストを取得するために次のコードが使用されます。

string errorText = GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, null /* modelState */);

modelState の null パラメータが渡されていることに注意してください。GetUserErrorMEssageOrDefault メソッドは、次のように始まります。

private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState) {
    if (!String.IsNullOrEmpty(error.ErrorMessage)) {
        return error.ErrorMessage;
    }
    if (modelState == null) {
        return null;
    }

    // Remaining code to fetch displayed string value...
}

そのため、ModelError.ErrorMessage プロパティが空の場合 (整数以外の値を宣言された int に設定しようとしたときに空であることを確認しました)、MVC は引き続き ModelState をチェックしますが、これは既に null であることを発見したため、null はException ModelError に対して返されます。したがって、この時点で、この問題に対する私の 2 つの最良の回避策は次のとおりです。

  1. ErrorMessage が設定されておらず、Exception が設定されている場合に適切なメッセージを正しく返すカスタム検証拡張機能を作成します。
  2. ModelState.IsValid が false を返す場合にコントローラーで呼び出される前処理関数を作成します。前処理関数は、ErrorMessage が設定されていないが Exception が設定されている ModelState の値を探し、ModelState.Value.AttemptedValue を使用して適切なメッセージを導き出します。

他のアイデアはありますか?

于 2009-09-01T18:48:50.400 に答える