2009-10-09 21 views
6

は非常に良いポストとASP.NET MVCで検証を実装する方法の説明がたくさんありますが、私はこれらの1好む:

しかし、私は本当に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つの検証のビルドになると私は信じています。

答えて

5

私はデータアノテーション属性を使用してAJAXを介して検証を成功させました。データの妥当性をチェックするには、コントローラーのModelStateプロパティーを使用します。プロパティーは、IsValidという独自のプロパティーを持っています。私は、公式のASP.NET MVCサイトからdata annotations validation attributes tutorialを覗いてみることを強くお勧めします。

最初に、別の名前とアカウント番号ではなく、モデルオブジェクトをパラメータとして受け入れるようにコントローラアクションを変更することをお勧めします。これにより、以下で説明するバリデーションをより簡単に行うことができます。あなたの例から、私の最高の推測は、あなたのモデルオブジェクトが顧客であるか、または顧客と呼ばれることでしょう。あなたのフォームフィールドがASPので、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 
    } 
} 


...モデルオブジェクトとあなたのコントローラのアクションを定義するには、次のコードを持っているかもしれません.NET MVCはそれらを自動的にバインドできます。この場合の「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ブロックを追加し、エラーメッセージをクライアントに表示するために必要な結果を返します。

+0

こんにちは!努力のためにたくさんありがとう:)私は結束のためのCustomerエンティティ(あなたが単純なパラメータでメソッドを置いていた理由は分かりませんでした)と確実に例外処理のためにあなたに完全に同意します。 xValを使用すると、クライアントの検証を簡単に実装することができます。もし誰かがそれを避けるなら、私はそれを実際に捕捉します。しかし、その場合フィールドの隣に検証メッセージをどのように表示するのですか? –

+0

そのためには、コントローラアクションからJSONではなく部分的なビューを返すことをお勧めします。部分ビューでは、Html.ValidationMessage()ヘルパーメソッドを使用して、各フィールドのエラーメッセージを表示します。 Data Annotations属性によって生成されたフィールドレベルのエラーメッセージは、 'ModelState'プロパティを介してコントローラで利用できます。たとえば、nameというフィールドの最初のエラーメッセージを取得するには、 'ModelState [" Name "]。Errors [0] .ErrorMessage'で取得します。また、 'Ajax.BeginForm'メソッドを見てください。私は過去に大きな成功を収めてきました。 –

+1

これは私が実現したことですが、JSONを部分ビューで返すか、それは好きではないことです...しかし、Ajaxの機能を組み込んだMSを使って対処する方法を見ていきます。私の願いは、それを回避することでした:)ありがとう –

2

あなたの質問をしてから1年以上が経過していますが、私はblog postのAjaxコールでサーバー側の検証を行いました。私はあなたが成功したHTTP呼び出しとして失敗した結果を返すことがわかります。私はこれを別の方法で処理しました($.ajaxsuccesserror応答機能の能力を持っているのでより正確です)。そして、あなたの特定の例は私のブログ記事で説明している機能で実装できる完璧な例です。

基本的には、常に成功した応答を返す代わりに(サーバー側の処理が失敗したことをクライアントに伝えるようにプロパティが設定されています)、むしろサーバー上で例外をスローし、それに従ってクライアント側で処理します。私はHandleModelStateExceptionアクションフィルタと共にカスタムModelStateExceptionクラスを使用しています。

関連する問題