2012-05-31 25 views
8

最近MVCを使い始めましたが、少し失望しています。私を助けてくれるのではなく、フレームワークが私の目の前に広がっています。私はこのようなコントローラのアクション(擬似コード)モデルバインディングを制御する方法は?

ActionResult Save(long id, string whichForm) 
{ 
    if (whichForm == "A") 
    { 
     var vm = CreateModel(Request.Form); 
     if (!TryValidate(vm)) 
      return View(vm); 
     else 
      return RedirectToRoute("Success"); 
    } 
    else .... 
} 

を書くしようとしている

基本的に私は私の見解モデルが構築されたときに、それが検証されたときのコントロールを持っているしたいと思います。これは可能ですか? CreateModelメソッドを実装するにはどうすればよいですか?私は、このコントローラアクション内にいくつかの異なるビューモデルを作成したいと考えています。

* Rant:ViewModelのバインディングと検証がDefaultModelBinderで混在している理由は分かりません。コードの臭いのようです。特にこの動作を無効にするのが難しい場合。

+1

downvoteありがとう、コメントを残して? :-) – Kugel

+0

+1彼らはあなたの* Rantが気に入らなかったかもしれませんが、あなたの意見には資格があります。質問の結果が良い答えである場合、問題はきれいなIMOです。 – AaronLS

答えて

16

自分の裁量で既存のモデルに作成してバインドすることができます:あなたがバインディングプロセスを完全に制御したい場合は、

public ActionResult Save(long id, string whichForm) 
{ 
    if (whichForm == "A") 
    { 
     var vm = new FormAViewModel(); 

     if (!TryUpdateModel(vm)) 
      return View(vm); 
     else 
      return RedirectToRoute("Success"); 
    } 
    // else .... 
} 

You also have the option of creating your own IModelBinder。既定のモデルバインダーを置き換えることも、特定の種類の特定のIModelBinder実装を登録することもできます。しかし、バインディングロジックがシンプルでない限り、カスタムモデルバインダーをDefaultModelBinderから派生させて、好きでない部分をオーバーライドしたいと思うことをお勧めします。

私はトロール・アイ・コメントを残したくないですが、フレームワークが実際にそれを使い方を理解していないために、フレームワークが途方もないと感じている理由は9回です。 Here is an article with general tips on model binding

あなたのrant:ValidationとBindingは別々ですが、デフォルトのモデルバインダーは検証をトリガーします。この理由は、アプリケーションが静的に失敗したり例外をスローするのではなく、不足している/無効な/不完全な値にバインドする問題を正常に処理できるようにするためです。

+0

ありがとう、私は完全にTryUpdateModelメソッドを逃しました。そして、私がかなり長い間検索してきたことを信じて、DefaultModelBinderとIModelBinderについて読んだことがあります。また、MVCのソースコードを見て... – Kugel

0

IModelBinderインターフェイスを活用して、完全なカスタムモデルバインダーを作成できます。ここでそれはよく説明されています。本質的に、このインタフェースはメソッドBindModelを公開します。ここでは、モデルのバインディング動作を検証とともに制御できます。

http://www.dotnetcurry.com/ShowArticle.aspx?ID=584

しかし、これは問題を複雑かもしれない、あなたはスパゲッティコードになるかもしれません。私は単純な "モデルごとのアクション"を提案します。だからこのようなものを書くことができます:

ActionResult SaveA(long id, AViewModel) 
{ 
     //.... Action to be conducted in case it is form A. 
} 
ActionResult SaveB(...., BViewModel) 
{ 
     //... Action to be conducted in case it is form B. 
} 


// Your view models can be structured for code reuse as well. 
class AViewModel { ... } 
class BViewModel : AViewModel { ... } 
+0

申し訳ありませんが、私の質問のポイントを逃した。 – Kugel

関連する問題