2013-05-14 8 views
36

はのは、私は、ユーザーの詳細情報の編集を可能にするページを持っているので、私はこのようにViewModelにあるとしましょう:ASP.NET MVC - どのように正確に使用するビューモデル

public class UserViewModel { 
    public string Username { get; set; } 
    public string Password { get; set; } 
    public int ManagerId { get; set; } 
    public string Category { get; set; } 
} 

だから私のEditUser作用に対するIこれは、モデルバインダーによって戻されていることができ、その後、私はドメインモデルにそれをマッピングすることができます

public ActionResult EditUser(UserViewModel user) { 
    ... 

しかし、フォームを表示するページでも、このようなためにドロップダウンを提供するために、管理者とカテゴリのリストなどの詳細を必要としますそれらのフィールド。サイドバーに他のユーザーのリストも表示されるので、編集中の異なるユーザーを切り替えることができます。

public class ViewUserViewModel { 
    public UserViewModel EditingUser { get; set; } 
    public IEnumerable<SelectListItem> Managers { get; set; } 
    public IEnumerable<SelectListItem> Categories { get; set; } 
    public IEnumerable<SelectListItem> AllUsers { get; set; } 
} 

これはそれを行うための正しい方法です:

だから、私は別のビューモデルを持っていますか?彼らはどちらもビューモデルですか?その場合は、モデルのようなVMとそのページのデータだけを含むVMを区別できるように、使用する命名規則はありますか?

これは間違っていますか?

答えて

20

私はショートカットでこれを行う方法:

  1. ごとに別々のViewModelクラスを作成します。フォームで、PartialViewsでこれらのクラスを@{Html.RenderPartial("PartialName", Model.PartialModel);}としてレンダリングします。
  2. ページにhtmlメタのようなものが含まれている場合は、メタのための別のクラスを作成し、ページのセクションに配置します。
  3. 「私はこれを別のクラスに入れるべきですか?あなたの判断です。

たとえば、ある種のログイン/登録バーやポップアップがあるページがあります。

public class SomePageViewModel 
{ 
    public RegisterBarVM Register { get; set; } 
    public LoginBarVM LoginBar { get; set; } 

    public MetasVM Metas { get; set; } 
    public string MaybePageTitle { get; set;} 
    public string MaybePageContent { get; set;} 

    [HiddenInput(DisplayValue = false)] 
    public int IdIfNeeded { get; set; } 

    public IEnumerable<SelectListItem> SomeItems {get; set;} 
    public string PickedItemId { get;set; } 
} 

public class RegisterBarVM 
{ 
    public string RegisterUsername {get;set;} 
    public string RegisterPassword {get;set;} 
    //... 
} 

public class LoginBarVM 
{ 
    public string LoginUserame {get;set;} 
    public string LoginPassword {get;set;} 
    //... 
} 

//cshtml 
@model yourClassesNamespace.SomePageViewModel 
@{ 
    Html.RenderPartial("LoginBar", Model.LoginBar); //form inside 
    Html.RenderPartial("RegisterBar", Model.RegisterBar); //form inside 

    using(Html.BeginForm()) 
    { 
     @Html.EditorFor(m => m.IdIfNeeded) 
     @Hmtl.EditorFor(m => m.MaybePageTitle) 
     @Hmtl.EditorFor(m => m.MaybePageContent) 

     @Hmtl.DropDownListFor(m => m.PickedItemId, new SelectList(Model.SomeItems)) 

     <input type="submit" value="Update" /> 
    } 
} 

@section Metas { 
    @{Html.RenderPartial("Meatas", Model.Metas} 
} 

Brad Wilsons Blogエディタテンプレートについて、ちょうどGoogleや表示/編集用テンプレートヘルパーやHTMLヘルパーについてのスタックのリソースを探してください。それらはすべて一貫したウェブサイトを構築するのに非常に便利です。

9

それはViewModelにの目的であるように私は個人的には、ViewModelににレンダリングするためにページに必要なすべての情報を置くことを好む - ビューのすべてのデータを提供します。だから私のUserViewModelManagersCategoriesAllUsersのプロパティを含んでいるでしょうし、コントローラは、ビューにオフのViewModelを渡す前に、それらのコレクションを埋めるだろう。それだけで式から余分のViewModelを削除 -

これは、あなたがやっていること、本質的です。

私も見てきた他のプログラマは、ビューにドロップダウンリストを送信するためのViewDataを使用しますが、ViewModelにはあるのに対し、私は、のViewDataが強く型付けされていないためということ嫌い。

93

「モデルの表示」は単なるパターンに過ぎません。そこ名程度魔法のようなものではませんが、一般的に任意のクラスは、(単にデータを表示するか、フォームの送信のためにかどうか)、「ビューモデル」と呼ばれ、FooViewModelまたはFooVMのような名前が与えられていることを示すためにビューに渡されますその "ビューモデル"パターンの一部です。

私はあなたにあまりにも哲学的に行きたくありませんが、私は劇中のパターンに関する参照の少しは参考になると思います。明らかにASP.NET MVCは、MVC(Model-View-Controller)アーキテクチャモデルを奨励します。 MVCでは、モデルはすべてのアプリケーションのビジネスロジックのコンテナです。コントローラは、要求を処理し、モデルをフェッチし、そのモデルでビューをレンダリングし、応答を返す責任があります。これは多くの責任のようですが、実際にはフレームワークが背後でこのような処理のほとんどを処理するので、コントローラは通常、コード上で非常に軽くなります。彼らはすべてを配線する機能を最低限必要としています。最後に、ビューは、ユーザーがモデル内のデータと対話できるようにするUIレイヤーを作成します。 はデータそのものではなく、実際には(ViewData/ViewBagは実際には開発者が使用する方法と同じくらい大きく違反しています)。

これは、アプリケーションロジックの大半がモデル内にあるべきことを意味します。通常、それは良いことです。しかし、モデルはアプリケーションデータの避難所なので、一般にデータベースなどに保持されます。これは、何のデータを持続させるべきか、どのデータを表示の目的のためだけに存在させるべきかのバランスの取れた行動を開始する必要があるので、いくつかの利益相反を生じさせます。

MVVM(Model-View-View Model)は、MVCとやや平行なパターンで、1つのモデルからすべてのルールに固有のアプローチの固有の問題を認識します。 MVCはこのパターンを使用しないので、ここでは詳しく説明しません。しかし、ほとんどのASP.NET MVC開発者は、MVVMのView Modelを共同で選択しました。基本的にはデータベースベースのエンティティ(従来のモデル)と、通常はさまざまな状態のエンティティを表すさまざまなビューモデルです。これにより、ビューモデルにそのモデルの表示、作成、更新に関連するビジネスロジックが含まれる間、永続性に関連するビジネスロジックをモデルに含めることができます。

私は少し外れてしまいましたが、あなたがやっていることは完全に受け入れられているということです。実際、それは良い習慣です。アプリケーションに必要な数のビューモデルを作成し、ビューに必要なデータとビジネスロジックを実際に格納するために使用します。 (これはSelectListのようなものを含んでいるあなたのコントローラやビューのいずれもドロップダウンのためのSelectListを作成する方法を知っておく必要があるはずです。。)

+6

この件に関する解説あなたはブログに入れてください! +1 –

+0

あなたは、モデルがアプリケーションのビジネスロジックを担当する必要があると述べました。ビジネスでは、おそらくすべてのデータの準備、クエリ、フィルタリング、あるモデルから別のモデルへの投影、または特定のViewModelを意味します。そして、そのように準備されたViewModelは、コントローラによってViewに渡されます。どのように物理的にそれを行うのですか?あなたはビジネスを行うためにどのようにモデルをデザインしていますか?たとえば、すべてのコントローラメソッドをビューモデルを表すクラスに移動しますか?現在、私は多くの機能とすべてのビットとボルトを行うコントローラの "ビジネス"を持っています。ありがとう – Celdor

+0

正直なところ、あなたは本当にASP.NET MVCでそれを行うことはできません。私が話していることを本当に理解するには、Ruby on Railsでサンプルアプリケーションを構築してください。 RoRは非常に厳密にMVCパターンに従っており、モデルにどのくらいのものが入っているのか正確に分かります。一方、ASP.NET MVCは、MVCにゆるやかにしか準拠していません。 「モデル」は、エンティティクラス、ビューモデル、リポジトリやサービスなどの何らかの組み合わせです。コントローラを薄くしておかなければなりません。すべてのロジックを1つのクラスに移動することはできません。 –

関連する問題