6

ASP.NET MVC で検証を実装する方法についての非常に優れた投稿と説明がたくさんありますが、私は次のいずれかを好みます。

ただし、jquery $.ajax メソッドを介して ActionMethods を呼び出すのが本当に好きです。$.ajax を使用したい理由の 1 つは、$.ajax 呼び出しを介して (エンティティ作成用のフォームでさえも) 動的にページに読み込まれる部分的なビューが多数あり、ビューを返すことができないためです。動的に読み込まれたすべてのコンテンツが失われます。

問題をよりよく理解できるように、簡単なコードを投稿して、コントローラーのアクションを呼び出し、クライアントの jquery コードで応答を処理する方法を説明します。

コントローラ ActionMethod:

    public ActionResult CreateCustomer(string name, string accountNumber)
    {
        try
        {
            CustomerService.InsertCustomer(name, accountNumber);

            return Json(new ActionInfo()
            {
                Success = true,
                Message = "Customer Is Successfully Created"
            });

        }
        catch (Exception ex)
        {
            return Json(new ActionInfo()
            {
                Success = false,
                Message = ex.Message
            });
        }
    }

クライアント コードでの呼び出しと処理:

$.ajax({
type: "POST",
url: $form.attr('action'),// /MyController/CreateCustomer
data: $form.serialize(),
error: HandleUnespectedError,
dataType: "json",
success: function(response) {

    if (response.Success)
        alert("Success: " + response.Message);
    else
        alert("Error: " + response.Message);
}});

これらの検証フレームワークのいくつかを必要な方法で機能させる良い方法はありますか? ActionInfo に検証エラーを追加し、それをクライアントで処理できることはわかっていますが、それはすでに 1 つの検証の構築に過ぎないと思います。

4

2 に答える 2

5

データ注釈属性を使用して、AJAX 経由で検証を行うことに成功しました。データの有効性を確認するには、コントローラーのModelStateプロパティを使用する必要があります。このプロパティには、 という独自のプロパティがありますIsValid。ASP.NET MVC の公式サイトにあるデータ注釈の検証属性のチュートリアルを参照することを強くお勧めします。

まず、コントローラ アクションを変更して、別の名前とアカウント番号ではなく、モデル オブジェクトをパラメータとして受け入れるようにします。これにより、以下で説明する検証の実行がはるかに簡単になります。あなたの例から、あなたのモデルオブジェクトはCustomerと呼ばれる、または呼ばれるだろうというのが私の最善の推測です。モデルオブジェクトとコントローラーアクションを定義する次のコードがあるかもしれません...

// model object
public class Customer
{
  public Int32 Id {get; set;}
  public String Name {get; set;}
  public String AccountNumber {get; set;}
}

// controller
public class CustomerController : Controller
{
  public ActionResult CreateCustomer( [Bind(Exclude = "Id")] Customer customer )
  {
     // controller action code
  }
}


ASP.NET MVC がそれらを自動的にバインドできるように、フォーム フィールドの名前が Customer オブジェクトのプロパティの名前と一致することを確認してください。この場合の "Bind" 属性は、フォーム フィールドをモデル プロパティにバインドするときに Customer クラスの "Id" プロパティを無視するよう ASP.NET MVC に指示しています。これは新しい顧客であるため、ID はまだありません。そのため、ID をデフォルト値のままにしておき、データ層を残して、それを生成する最善の方法を見つけ出すことができます。

コントローラーがアクション メソッドのモデル オブジェクトを構築すると、その有効性はプロパティを介して簡単に確認できますModelState.IsValid。ご想像のとおり、モデル プロパティが有効な場合は true を返し、1 つ以上のプロパティが無効な場合は false を返します。

元の質問から、CustomerService.InsertCustomer検証が失敗したときにメソッドが例外をスローしているようです。これは完全に不要です。InsertCustomer は、新しいレコードを挿入するために必要なデータ操作のみを実行する必要があります。SqlException のような実装固有の例外を抽象化したい場合を除き、InsertCustomer は実際に例外をキャッチまたはスローする必要はありませんが、ほとんどの場合、例外をコントローラー (または呼び出し元が誰であれ) にバブルアップさせることができます。

これらすべての最終結果は、次のようなコントローラー アクションになる可能性があります。

public ActionResult CreateCustomer( [Bind(Exclude = "Id")] Customer customer )
{
  // model is invalid
  if (!ModelState.IsValid)
  {
    return Json(new ActionInfo()
    {
      Success = false,
      Message = "Validation failed" // you will probably want a more robust message :-)
    });
  }

  // service method accepts a Customer object rather than arbitrary strings  
  CustomerService.InsertCustomer(customer);

  return Json(new ActionInfo()
  {
    Success = true,
    Message = "Customer created successfully."
  });

}


データベース関連の例外などの予期しないエラーを報告する場合は、InsertCustomer の呼び出しの周りに try/catch ブロックを追加して、エラー メッセージを表示するために必要な結果をクライアントに返すことができます。

于 2009-10-15T07:02:14.910 に答える
2

質問をしてから1年以上経ちますが、ブログ投稿でAjax呼び出しを使用したサーバー側の検証について説明しましたが、これは非常に興味深いものです。失敗した結果を成功したHTTP呼び出しとして返すようです。私はこれを別の方法で処理しました(機能と応答機能$.ajaxがあるので、より正しいと思います)。そして、あなたの特定の例は、ブログ投稿で説明した機能を使用して実装できる完璧な例です。successerror

基本的に、常に成功した応答を返す代わりに(ただし、サーバー側の処理が失敗したことをクライアントに通知するようにプロパティを設定して)、サーバーでexeceptionをスローし、それに応じてクライアントで処理します。HandleModelStateExceptionアクションフィルターと一緒にカスタムModelStateExceptionクラスを使用しています。

于 2010-11-27T11:04:40.780 に答える