10

最近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:DefaultModelBinderでビューモデルのバインドと検証が混在している理由がよくわかりません。コードの臭いのようです。特に、この動作を無効にするのが難しい場合。

4

2 に答える 2

22

自由裁量で既存のモデルを作成してバインドできます。

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 ....
}

IModelBinderバインディングプロセスを完全に制御したい場合は、独自のを作成するオプションもあります。IModelBinderデフォルトのモデルバインダーを置き換えるか、特定のタイプの特定の実装を登録できます。ただし、バインディングロジックが単純でない限り、カスタムモデルバインダーを派生させて、不要DefaultModelBinderな部分をオーバーライドすることをお勧めします。

荒らしのようなコメントを残すのは嫌いですが、フレームワークが邪魔になっていると感じる理由は10回のうち9回です。これは、フレームワークの適切な使用方法をまだ理解していないためです。これは、モデルバインディングに関する一般的なヒントの記事です。

あなたの暴言に関して:検証とバインディングは別々ですが、デフォルトのモデルバインダーは検証をトリガーします。これは、バインディングがサイレントに失敗したり例外をスローしたりするのではなく、アプリケーションが欠落/無効/不完全な値にバインドする問題を適切に処理できるようにするためです。

于 2012-05-31T00:21:57.430 に答える
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 {  ...  }
于 2012-05-31T00:24:36.897 に答える