2

Asp Mvc3 アプリがあります。私の見解では、剣道+ノックアウトjsを使用しています。剣道バリデーターでクライアント側の検証を処理しています。私はasp mvc3に非常に慣れていないため、サーバー側の検証を機能させることができません。

これは私のビジネスオブジェクトです:

[Validator(typeof(FranchiseInfoValidator))]
    public class FranchiseInfo
    {
        public string FullName { get; set; }
        public string ShortName { get; set; }
    }
}

FluentValidation を使用しています。これは私の検証ルールの実装です:

public class FranchiseInfoValidator : AbstractValidator<FranchiseInfo>
    {
        public FranchiseInfoValidator()
        {
            RuleFor(franchiseInfo => franchiseInfo.FullName).NotEmpty();
            RuleFor(franchiseInfo => franchiseInfo.ShortName).NotEmpty();
        }
    }

これは私のビューモデルです:

public class FranchiseInfoViewModel
    {
        public string FullName { get; set; }
        public string ShortName { get; set; }
    }

これは FranchiseInfoViewModel に強く型付けされた私のビューです。

@model MvcApplication2.Models.FranchiseInfoViewModel

<script src="../../Scripts/Details.js" type="text/javascript"></script>

<form id="franchiseForm" action="" style="font-family: Trebuchet MS, Verdana, Helvetica, Sans-Serif;"> 
     <table>
            <tr>
                <td><label for="fullName">FullName:</label></td>
                <td><input id="fullName" data-bind= "value: FullName" /></td>
            </tr>
            <tr>
                <td><label for="shortName">ShortName:</label></td>
                <td><input id="shortName" data-bind= "value: shortName" /></td>
            </tr>
    </table>
    <button id="submit" class="k-button" data-bind="click: save" form="franchiseForm">Save Franchise</button>
</form>

フォームを送信すると、javascript 関数を呼び出して保存します。

$(function () {

    save = function () {

        // some logic

        $.ajax({
            url: "/franchise/SaveFranchise",
            type: "POST",
            data: { franchiseInfoViewModel: jsonData },               
            dataType: 'json',
            success: function (data, textStatus, xhr) {
                window.location.href = data.redirectToUrl;
            }
        });
    }
});

保存時に、データを json 形式で送信し、そのデータを SaveFranchise Controller に送信しています。

public ActionResult SaveFranchise(string franchiseInfoViewModel)
        {
            var franchiseInfoVM = JsonConvert.DeserializeObject<FranchiseInfoViewModel>(franchiseInfoViewModel);

            if (!ModelState.IsValid)
            { 
                // do some action
            }

            return View();
        }

私が達成したいのは(!ModelState.IsValid)、ビューに戻って流暢な検証エラー メッセージを表示することです。どういうわけか、私の場合、ModelState.IsValid は常に true です。

前述のように、私は Asp Mvc 3 に非常に慣れていません。私が読んだ記事から、例はフォームをサーバーに送信し (javascript なしで)、バインディングがあり、サーバー検証メッセージがビューに返されます。ただし、ビューは Razor で実装され、クライアント側の検証は jquery を介して行われます。

私の見解では、データバインディング(剣道+ノックアウト)でjavascriptビューモデルを使用しています。私の場合、サーバー側の検証を行うにはどうすればよいですか。私を助けてください。お時間とご尽力いただきありがとうございます。

4

1 に答える 1

5

簡潔な答え:

コントローラー アクションでモデル バインディングを使用する必要があります。これにより、 を使用できるようになりますModelState.IsValid

したがって、コントローラーのアクションは次のとおりです。

public ActionResult SaveFranchise(string franchiseInfoViewModel)

.. 次のように変更する必要があります。

public ActionResult Create(FranchiseInfo franchiseInfo)

モデル バインダーがモデルのインスタンスをインスタンス化できる形式でフォームを投稿してくださいFranchiseInfoactionJSON を使用してこれを行うこともできますが、フォームの標準属性を使用してフォームを投稿するだけの方が良い (そして簡単になる) と思います。

詳細な回答:

最初にお勧めすることの 1 つは、ASP.NET MVC フレームワークによって提供されるモデル検証を使用することです。これには、サーバー側検証用のモデル バインディング、モデル状態、データ注釈、およびクライアント側検証用の控え目な JavaScript が含まれます。そうすることで、明確な懸念の分離 (SoC) を備えた、よりDRYな実装が可能になります。

そこにたどり着くには、まず ASP.NET MVC のモデル バインディングを確認することをお勧めします。

「ASP.NET MVC モデル バインディングの機能と欠点」に記載されているとおり:

モデル バインディングを使用すると、コントローラー アクションをビジネス価値の提供に集中させることができ、ありふれた要求のマッピングと解析で時間を無駄にすることを回避できます。

これを確認するには、このMSDN 記事にモデル バインダーの適切な定義があります。

MVC のモデル バインダーは、ポストされたフォームの値を .NET Framework 型にマップし、その型をパラメーターとしてアクション メソッドに渡す簡単な方法を提供します。(...) モデル バインダーは、HTTP 要求をアクション メソッドに渡されるオブジェクトに変換できるため、型コンバーターに似ています。

その抽象化を手にすると、次の署名がすぐにわかります。

public ActionResult SaveFranchise(string franchiseInfoViewModel)

.. 次のように変更できます。

public ActionResult Create(FranchiseInfo franchiseInfo)

...そして、この時点で、コードがカスタム データ マッピングのようになるため、物事はすでによりきれいに見え始めています。

var franchiseInfoVM = JsonConvert.DeserializeObject<FranchiseInfoViewModel>(franchiseInfoViewModel);

...取り外し可能です。

一般に、フォームを JSON にシリアル化して投稿する必要はありません。代わりに、MVC のモデル バインディングを利用して、標準的な方法でフォーム データを送信する必要があります (actionフォーム要素の属性を使用して、モデルバインダーは JSON に基づいてオブジェクトをバインドできますが、私の主張は理解できると思います.. )。実際、ASP.NET MVC を使用すると、モデルのフォームを簡単に生成できます。Html.BeginFormこれの使用例をここに示します

したがって、フォーム データを JSON にシリアル化せずにデータをポストするフォームを使用するようにビューをリファクタリングしたら、MVC3 のデータ アノテーションを確認する必要があります。

この例で述べたようにSystem.ComponentModel.DataAnnotations、.NET の名前空間は...

は、任意のクラスまたはプロパティに宣言的に適用できる組み込みの検証属性のセットを提供します。(...) 検証属性は、適用先のモデル プロパティに適用する動作を指定します。

利用可能な注釈の 1 つはRequired属性です。これは、特定のモデル プロパティに値が必要であることを定義します。、 、など、他にもいくつかの属性があります。いくつかの属性の使用例は次のようになります。RangeMaxLengthRegularExpression

public class Movie
{
    public int ID { get; set; }

    [Required(ErrorMessage = "Title is required")]
    public string Title { get; set; }

    [Required(ErrorMessage = "Date is required")]
    public DateTime ReleaseDate { get; set; }

    [Required(ErrorMessage = "Genre must be specified")]
    public string Genre { get; set; }

    [Required(ErrorMessage = "Price Required")]
    [Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
    public decimal Price { get; set; }

    [StringLength(5)]
    public string Rating { get; set; }
}

(例は次から借用しています: http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/cs/adding-validation-to-the-model )

モデルにデータ注釈を入力すると、特定のフォームが送信された時点でモデルが有効かどうかを簡単に確認でき、特定のアクションで提供されたモデルの有効性を確認することができます -ここModelState.IsValidにあると便利です。

この投稿で述べたように:

(...) 2 番目の Create メソッドはModelState.IsValid、ムービーに検証エラーがあるかどうかを確認するために呼び出します。このメソッドを呼び出すと、オブジェクトに適用された検証属性が評価されます。

したがって、この時点で、データ注釈を使用してモデルの制約/必要な動作を宣言すると、ロジックがモデルで定義され、ModelState.IsValid.

これを少し詳しく説明するために、ASP.NET MVC3 のサーバー側とクライアント側でのモデル検証に関する私の経験を少しお話しします。

既にお察しのとおり、モデルの検証に関して ASP.NET MVC3 を使用した私の最高の経験は、データ注釈と、ModelState.IsValid目立たない JavaScript によるサーバー側検証とクライアント側検証の組み込みサポートを使用することです。

データ注釈には、組み込みの注釈と、データ注釈拡張プロジェクトによって提供される拡張機能を組み合わせて使用​​します。

ASP.NET MVC3 の控えめなクライアント検証のサポートを使用することには、いくつかの利点があります。

  • まず第一に、SoCは非常に簡単に実現できます。モデルの検証ロジックは 1 か所でしか定義されていないためです。つまり、SoC が属するモデル内です。
  • 次に、ビューでよりDRYな実装を取得し (ロジックの重複を避け、保守しやすいコードを取得します)、代わりにフレームワークに面倒な作業を任せることができます。

ASP.NET MVC3 で目立たないクライアント側の検証を使用する方法の例は、 ここにあります。

ただし、クレジット カードやファイル拡張子などのプロパティを検証する場合など、注釈の使用がそれほど簡単に思えない場合もあります。基本的なアノテーション以外のロジック呼び出しが必要なこれらのケースでは、データ アノテーション拡張機能を使用する傾向があります (たとえば、一連の属性を追加した.NET 4.5 用のアプリケーションをターゲットにできない限り、たとえば、 )はFileExtensionAttribute、箱から出してすぐに機能する一連の優れた注釈拡張機能を提供するためです(MVC3用のデータ注釈拡張機能nugetパッケージが存在するため、セットアップして使用を開始するのは非常に簡単です).

また、データベースの状態に依存するプロパティを持つ特殊なケースもあります。たとえば、ユーザーがユーザー登録フォームに入力するときにユーザー名が既に存在するかどうかを確認する場合などです。このシナリオでは、ASP.NET MVC3 リモート検証アノテーションが役に立ちます。このMSDNの記事にあるように

ASP.NET MVC 3 は、フォーム全体をサーバーに送信せずにフォーム フィールドを検証するために、リモート サーバー呼び出しを行うことができるメカニズムを提供します。これは、クライアントで検証できないフィールドがあり、フォームの送信時に検証に失敗する可能性が高い場合に役立ちます。

また、ASP.NET MVC3 でのリモート検証の優れた点は、データ注釈を使用して表現されることです (このブログ投稿とこの MSDN 記事に示されているよう)

要約すると、これらのフレームワーク機能 (imo) を使用すると、ASP.NET MVC3 で多かれ少なかれあらゆる種類のモデル検証を「正しい方法で」カバーするための本格的なツールが提供されます。

于 2012-08-31T23:22:59.933 に答える