web-dev-qa-db-ja.com

MVCのViewModelとは何ですか?

私はASP.NET MVCが初めてです。 ViewModelの目的を理解するのに問題があります。

ViewModelとは何ですか。また、ASP.NET MVCアプリケーションにViewModelが必要なのはなぜですか。

簡単な例があればもっといいです。

387
unique

view modelは、ビューまたはページに表示するデータを表します。静的テキストに使用するか、データベースに追加(または編集)できる入力値(テキストボックスやドロップダウンリストなど)に使用します。それはあなたのdomain modelとは違うものです。それは見解のモデルです。

従業員ドメインモデルを表すEmployeeクラスがあり、それには次のプロパティ(一意の識別子、名、姓および作成日)が含まれているとします。

public class Employee : IEntity
{
     public int Id { get; set; }

     public string FirstName { get; set; }

     public string LastName { get; set; }

     public DateTime DateCreated { get; set; }
}

ビューモデルには、ビューで使用するデータ(プロパティで表される)のみが含まれるという点で、ドメインモデルとは異なります。たとえば、新しい従業員レコードを追加するとします。ビューモデルは次のようになります。

public class CreateEmployeeViewModel
{
     public string FirstName { get; set; }

     public string LastName { get; set; }
}

ご覧のとおり、2つのプロパティしか含まれていません。これら2つのプロパティは、従業員ドメインモデルにもあります。これはなぜあなたが尋ねるのですか? Idはビューから設定されていないかもしれません、それはEmployeeテーブルによって自動生成されるかもしれません。また、DateCreatedはストアドプロシージャまたはアプリケーションのサービス層にも設定できます。そのため、ビューモデルではIdDateCreatedは必要ありません。従業員の詳細(すでに取得済みの従業員)を静的テキストとして表示するときに、これら2つのプロパティを表示することをお勧めします。

ビュー/ページをロードすると、従業員コントローラのアクション作成メソッドはこのビューモデルのインスタンスを作成し、必要に応じてフィールドに値を入力してから、このビューモデルをビュー/ページに渡します。

public class EmployeeController : Controller
{
     private readonly IEmployeeService employeeService;

     public EmployeeController(IEmployeeService employeeService)
     {
          this.employeeService = employeeService;
     }

     public ActionResult Create()
     {
          CreateEmployeeViewModel model = new CreateEmployeeViewModel();

          return View(model);
     }

     public ActionResult Create(CreateEmployeeViewModel model)
     {
          // Do what ever needs to be done before adding the employee to the database
     }
}

あなたのビュー/ページはこのように見えるかもしれません(あなたがASP.NET MVCRazorビューエンジンを使っていると仮定して):

@model MyProject.Web.ViewModels.CreateEmployeeViewModel

<table>
     <tr>
          <td><b>First Name:</b></td>
          <td>@Html.TextBoxFor(m => m.FirstName, new { maxlength = "50", size = "50" })
              @Html.ValidationMessageFor(m => m.FirstName)
          </td>
     </tr>
     <tr>
          <td><b>Last Name:</b></td>
          <td>@Html.TextBoxFor(m => m.LastName, new { maxlength = "50", size = "50" })
              @Html.ValidationMessageFor(m => m.LastName)
          </td>
     </tr>
</table>

したがって、検証はFirstNameLastNameに対してのみ行われます。 流暢な検証を使う あなたはこのような検証をするかもしれない:

public class CreateEmployeeViewModelValidator : AbstractValidator<CreateEmployeeViewModel>
{
     public CreateEmployeeViewModelValidator()
     {
          RuleFor(m => m.FirstName)
               .NotEmpty()
               .WithMessage("First name required")
               .Length(1, 50)
               .WithMessage("First name must not be greater than 50 characters");

          RuleFor(m => m.LastName)
               .NotEmpty()
               .WithMessage("Last name required")
               .Length(1, 50)
               .WithMessage("Last name must not be greater than 50 characters");
     }
}

そして、Data Annotationsの場合、これは次のようになります。

public class CreateEmployeeViewModel : ViewModelBase
{
    [Display(Name = "First Name")]
    [Required(ErrorMessage = "First name required")]
    public string FirstName { get; set; }

    [Display(Name = "Last Name")]
    [Required(ErrorMessage = "Last name required")]
    public string LastName { get; set; }
}

覚えておくべき重要なことは、ビューモデルはあなたが使いたいデータを表しているだけであるということです _、他には何もありません。 30個のプロパティを持つドメインモデルがあり、単一の値のみを更新したい場合は、不要なコードと検証をすべて想像できます。このシナリオでは、ビューモデルには1つの値/プロパティしかなく、ドメインオブジェクトにあるすべてのプロパティはありません。

ビューモデルには、1つのデータベーステーブルのデータだけが含まれているわけではありません。他のテーブルのデータを組み合わせることができます。新しい従業員レコードを追加することについて、上の例を見てください。姓と名だけを追加するだけでなく、従業員の部署を追加することもできます。この部門のリストはあなたのDepartmentsテーブルから来ます。これで、1つのビューモデルにEmployeesテーブルとDepartmentsテーブルのデータがあります。その後、ビューモデルに次の2つのプロパティを追加してデータを追加するだけです。

public int DepartmentId { get; set; }

public IEnumerable<Department> Departments { get; set; }

従業員データ(すでにデータベースに追加されている従業員)を編集するときは、上の例とそれほど違いはありません。ビューモデルを作成し、それを例えばEditEmployeeViewModelと呼びます。このビューモデルでは、姓や名など、編集するデータのみを持っています。データを編集して送信ボタンをクリックします。 Idの値はおそらくURLに含まれるので、私はIdフィールドについてはそれほど心配しないでください。例えば:

http://www.yourwebsite.com/Employee/Edit/3

このIdを取り、あなたの名前と姓の値とともに、それをあなたのリポジトリ層に渡してください。

レコードを削除するとき、私は通常編集ビューモデルと同じパスをたどります。また、URLもあります。

http://www.yourwebsite.com/Employee/Delete/3

ビューが初めてロードされたとき、私は3のIdを使用してデータベースから従業員のデータを取得します。その後、ユーザーが削除されている従業員を確認できるようにビュー/ページに静的テキストを表示します。ユーザーが[削除]ボタンをクリックすると、Idの値として3が使用され、それが自分のリポジトリ層に渡されます。テーブルからレコードを削除するために必要なのはIdだけです。

もう1つのポイントは、すべてのアクションにビューモデルを必ずしも必要としないということです。それが単純なデータであるならば、EmployeeViewModelのみを使用するのが良いでしょう。それが複雑なビュー/ページであり、それらが互いに異なる場合は、それぞれに別々のビューモデルを使用することをお勧めします。

これにより、ビューモデルとドメインモデルについての混乱が解消されるでしょう。

558
Brendan Vogt

ビューモデル は、特定のビューで使用されるデータモデルを表すクラスです。このクラスをログインページのモデルとして使用できます。

public class LoginPageVM
{
    [Required(ErrorMessage = "Are you really trying to login without entering username?")]
    [DisplayName("Username/e-mail")]
    public string UserName { get; set; }
    [Required(ErrorMessage = "Please enter password:)")]
    [DisplayName("Password")]
    public string Password { get; set; }
    [DisplayName("Stay logged in when browser is closed")]
    public bool RememberMe { get; set; }
}

このビューモデルを使ってビューを定義できます(Razorビューエンジン)。

@model CamelTrap.Models.ViewModels.LoginPageVM

@using (Html.BeginForm()) {
    @Html.EditorFor(m => m);
    <input type="submit" value="Save" class="submit" />
}

そして行動:

[HttpGet]
public ActionResult LoginPage()
{
    return View();
}

[HttpPost]
public ActionResult LoginPage(LoginPageVM model)
{
    ...code to login user to application...
    return View(model);
}

これにより、この結果が生成されます(画面はフォームの送信後に検証メッセージと共に表示されます)。

ご覧のとおり、ビューモデルには多くの役割があります。

  • ビューモデルは、ビューに表示されているフィールドのみで構成されてビューを文書化します。
  • ビューモデルには、データ注釈またはIDataErrorInfoを使用した特定の検証規則を含めることができます。
  • ビューモデルはビューの外観を定義します(LabelForEditorForDisplayForヘルパーの場合)。
  • ビューモデルは、異なるデータベースエンティティからの値を組み合わせることができます。
  • ViewForまたはEditorForヘルパーを使用して、ビューモデルの表示テンプレートを簡単に指定してさまざまな場所で再利用できます。

ビューモデルとその検索のもう1つの例:基本的なユーザーデータ、その特権、ユーザー名を表示したいと思います。必要なフィールドだけを含む特別なビューモデルを作成します。データベースからさまざまなエンティティからデータを取得しますが、ビューはビューモデルクラスのみを認識します。

public class UserVM {
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool IsAdministrator { get; set; }
    public string MothersName { get; set; }
}

検索:

var user = db.userRepository.GetUser(id);

var model = new UserVM() {
   ID = user.ID,
   FirstName = user.FirstName,
   LastName = user.LastName,
   IsAdministrator = user.Proviledges.IsAdministrator,
   MothersName = user.Mother.FirstName + " " + user.Mother.LastName
} 
128
LukLed

編集:私は私のブログでこの答えを更新しました:

http://www.samwheat.com/Post/The-function-of-ViewModels-in-MVC-web-development

私の答えは少し長いですが、なぜそれらが違うのか、そしてなぜそれらが必要なのかを理解するためにビューモデルを他のタイプの一般的に使われるモデルと比較することが重要だと思います。

まとめるために、そして尋ねられる質問に直接答えるために:

一般的に言って、ビューモデルはビューをレンダリングするのに必要なすべてのプロパティとメソッドを含むオブジェクトです。ビューモデルのプロパティは、顧客や注文などのデータオブジェクトに関連することが多く、さらに、ユーザー名、アプリケーション名など、ページまたはアプリケーション自体に関連するプロパティも含まれています。ビューモデルは、レンダリングエンジンに渡す便利なオブジェクトを提供します。 HTMLページを作成します。ビューモデルを使用する多くの理由の1つは、ビューモデルが、ユーザー入力の処理、データの検証、表示用のデータの取得などの特定のプレゼンテーションタスクをユニットテストする方法を提供することです。

これはエンティティモデル(別名DTOの別名モデル)、プレゼンテーションモデル、およびビューモデルの比較です。

データ転送オブジェクトa.k.a“モデル”

データ転送オブジェクト(DTO)は、データベース内のテーブルスキーマと一致するプロパティを持つクラスです。 DTOは、データストアとの間でデータをやり取りするための一般的な使用法に基づいています。
DTOの特徴:

•ビジネスオブジェクト - 定義はアプリケーションデータに依存します。

•通常はプロパティのみを含みます。コードは含みません。

•主にデータベースとの間のデータ転送に使用されます。

•プロパティは、データストア内の特定のテーブルのフィールドと完全に一致する。

データベーステーブルは通常正規化されているのでDTOも通常正規化されています。これは彼らにデータを提示するための限られた用途になります。ただし、特定の単純なデータ構造の場合、それらは非常によく機能します。

これがDTOの外観の例です。

public class Customer
{
    public int ID { get; set; }
    public string CustomerName { get; set; }
}


public class Order
{
    public int ID { get; set; }
    public int CustomerID { get; set; }
    public DateTime OrderDate { get; set; }
    public Decimal OrderAmount { get; set; }
}

プレゼンテーションモデル

プレゼンテーションモデルは、画面またはレポートにデータを表示するために使用されるutilityクラスです。プレゼンテーションモデルは通常、複数のDTOのデータから構成される複雑なデータ構造をモデル化するために使用されます。プレゼンテーションモデルは、データの非正規化ビューを表すことがよくあります。

プレゼンテーションモデルの特徴

•ビジネスオブジェクト - 定義はアプリケーションデータに依存します。

•主にプロパティを含みます。コードは通常、データのフォーマット、またはDTOとの間の変換に限定されています。プレゼンテーションモデルはビジネスロジックを含むべきではありません。

•データの非正規化ビューを表示することがよくあります。つまり、複数のDTOからのプロパティを組み合わせることがよくあります。

•DTOとは異なる基本型のプロパティを含むことがよくあります。たとえば、ドル金額は文字列として表すことができるので、コンマと通貨記号を含めることができます。

•多くの場合、それらがどのように使用されているか、およびそれらのオブジェクトの特性によって定義されます。言い換えると、グリッドをレンダリングするためのバッキングモデルとして使用される単純なDTOは、実際にはそのグリッドのコンテキストにおけるプレゼンテーションモデルでもあります。

プレゼンテーションモデルは、「必要に応じて」および「必要に応じて」使用されます(DTOは通常データベーススキーマに関連付けられています)。プレゼンテーションモデルは、ページ全体、ページ上のグリッド、またはページ上のグリッド上のドロップダウンのデータをモデル化するために使用できます。プレゼンテーションモデルには、他のプレゼンテーションモデルのプロパティが含まれていることがよくあります。プレゼンテーションモデルは、単一のページに特定のグリッドを描画するなど、使い捨ての目的で作成されることがよくあります。

プレゼンテーションモデルの例:

public class PresentationOrder
{
    public int OrderID { get; set; }
    public DateTime OrderDate { get; set; }
    public string PrettyDate { get { return OrderDate.ToShortDateString(); } }
    public string CustomerName { get; set; }
    public Decimal OrderAmount { get; set; }
    public string PrettyAmount { get { return string.Format("{0:C}", OrderAmount); } }
}

モデルを見る

ビューモデルは、ビューをレンダリングするためのバッキングクラスであるという点でプレゼンテーションモデルに似ています。ただし、プレゼンテーションモデルやDTOとは、その構築方法が大きく異なります。ビューモデルには、プレゼンテーションモデルやDTOと同じプロパティが含まれていることが多く、そのため、これらは互いに混同されています。

ビューモデルの特徴:

•ページまたは画面をレンダリングするために使用される単一のデータソースです。通常これは、ビューモデルが、ページ上の任意のコントロールがそれ自体を正しくレンダリングするために必要なすべてのプロパティを公開することを意味します。ビューモデルをビューの単一データソースにすると、その機能と単体テストの価値が大幅に向上します。

複合オブジェクト アプリケーションデータで構成されるプロパティとアプリケーションコードで使用されるプロパティを含みます。この特性は、再利用可能性のためにビューモデルを設計するときにきわめて重要であり、以下の例で説明されています。

•アプリケーションコードを含める。ビューモデルには通常、レンダリング中およびユーザーがページを操作しているときに呼び出されるメソッドが含まれています。このコードは通常、イベント処理、アニメーション、コントロールの表示、スタイルなどに関連しています。

•データの取得またはデータベースサーバへの送信を目的としてビジネスサービスを呼び出すコードを含める。このコードはしばしば誤ってコントローラに入れられます。コントローラからビジネスサービスを呼び出すと、通常、単体テストのビューモデルの有用性が制限されます。明確にするために、ビューモデル自体はビジネスロジックを含むべきではなく、ビジネスロジックを含むサービスを呼び出すべきです。

•他のページや画面の他のビューモデルであるプロパティを含むことがよくあります。

•「ページごと」または「画面ごと」と書かれています。固有のビューモデルは通常、アプリケーション内のすべてのページまたは画面に対して作成されます。

•ほとんどのページと画面は共通のプロパティを共有しているため、通常は基本クラスから派生します。

モデル構成を見る

前述のように、ビューモデルは、アプリケーションプロパティとビジネスデータプロパティを単一のオブジェクトに結合するという点で複合オブジェクトです。ビューモデルで使用される一般的に使用されるアプリケーションプロパティの例は次のとおりです。

•エラーメッセージ、ユーザー名、ステータスなど、アプリケーションの状態を表示するために使用されるプロパティ.

•コントロールの書式設定、表示、スタイル設定、またはアニメーション化に使用されるプロパティ。

•リストオブジェクトや、ユーザーが入力した中間データを保持するプロパティなど、データバインディングに使用されるプロパティ。

次の例は、ビューモデルの複合的な性質が重要である理由と、効率的で再利用可能なビューモデルを最適に構築する方法を示しています。

Webアプリケーションを書いているとしましょう。アプリケーション設計の要件の1つは、ページタイトル、ユーザー名、およびアプリケーション名をすべてのページに表示する必要があることです。プレゼンテーション注文オブジェクトを表示するページを作成したい場合は、プレゼンテーションモデルを次のように変更します。

public class PresentationOrder
{
    public string PageTitle { get; set; }
    public string UserName { get; set; }
    public string ApplicationName { get; set; }
    public int OrderID { get; set; }
    public DateTime OrderDate { get; set; }
    public string PrettyDate { get { return OrderDate.ToShortDateString(); } }
    public string CustomerName { get; set; }
    public Decimal OrderAmount { get; set; }
    public string PrettyAmount { get { return string.Format("{0:C}", OrderAmount); } }
}

このデザインはうまくいくかもしれません…でも、注文のリストを表示するページを作成したいとしたらどうでしょうか。 PageTitle、UserName、およびApplicationNameの各プロパティは繰り返し使用されるため、扱いにくくなります。また、クラスのコンストラクタでページレベルのロジックを定義したいとしたらどうでしょうか。表示されるすべての注文に対してインスタンスを作成した場合、これを行うことはできません。

継承に対する構成

これが真のビューモデルになり、単一のPresentationOrderオブジェクトまたはPresentationOrderオブジェクトのコレクションを表示するのに役立ちます。

public class PresentationOrderVM
{
    // Application properties
    public string PageTitle { get; set; }
    public string UserName { get; set; }
    public string ApplicationName { get; set; }

    // Business properties
    public PresentationOrder Order { get; set; }
}


public class PresentationOrderVM
{
    // Application properties
    public string PageTitle { get; set; }
    public string UserName { get; set; }
    public string ApplicationName { get; set; }

    // Business properties
    public List<PresentationOrder> Orders { get; set; }
}

上記の2つのクラスを見ると、ビューモデルについて考える1つの方法は、それがプロパティとして別のプレゼンテーションモデルを含むプレゼンテーションモデルであるということです。トップレベルのプレゼンテーションモデル(すなわちビューモデル)はページまたはアプリケーションに関連するプロパティを含み、プレゼンテーションモデル(プロパティ)はアプリケーションデータに関連するプロパティを含む。

さらに設計を進めて、PresentationOrdersだけでなく他のクラスにも使用できる基本ビューモデルクラスを作成できます。

public class BaseViewModel
{
    // Application properties
    public string PageTitle { get; set; }
    public string UserName { get; set; }
    public string ApplicationName { get; set; }
}

これで、PresentationOrderVMを次のように単純化できます。

public class PresentationOrderVM : BaseViewModel
{
    // Business properties
    public PresentationOrder Order { get; set; }
}

public class PresentationOrderVM : BaseViewModel
{
    // Business properties
    public List<PresentationOrder> Orders { get; set; }
}

BaseViewModelを汎用にすることで、さらに再利用可能にすることができます。

public class BaseViewModel<T>
{
    // Application properties
    public string PageTitle { get; set; }
    public string UserName { get; set; }
    public string ApplicationName { get; set; }

    // Business property
    public T BusinessObject { get; set; }
}

今私たちの実装は楽です:

public class PresentationOrderVM : BaseViewModel<PresentationOrder>
{
    // done!
}

public class PresentationOrderVM : BaseViewModel<List<PresentationOrder>>
{
    // done!
}
74
Sam

ビューに固有のプロパティがあり、DB/Service/Dataストアに関連していない場合は、ViewModelを使用することをお勧めします。たとえば、DBフィールド(または2つ)に基づいてチェックボックスを選択したままにしたいが、DBフィールド自体はブール値ではありません。モデル自体にこれらのプロパティを作成してデータへのバインディングから隠すことは可能ですが、そのようなフィールドやトランザクションの量によっては、モデルを乱雑にしたくない場合があります。

ビュー固有のデータや変換が少なすぎる場合は、モデル自体を使用できます。

22
fozylet

すべての記事を読んだわけではありませんが、すべての答えに1つの概念が欠けているようです。

モデルがデータベースと似ている場合 Table である場合、ViewModelはデータベースと似ている View - ビューは通常、次のいずれかから少量のデータを返します。 1つのテーブル、または複数のテーブルからの複雑なデータセット(結合)。

ViewModelsを使って情報をビュー/フォームに渡し、フォームがコントローラにポストバックするときにそのデータを有効なModelに転送します。これはリストを格納するのにも非常に便利です(IEnumerable)。

16
halfacreSal

MVCはビューモデルを持っていません:それはモデル、ビューとコントローラを持っています。ビューモデルはMVVM(Model-View-Viewmodel)の一部です。 MVVMは、プレゼンテーションモデルから派生したもので、WPFで普及しています。 MVVMにもモデルがあるはずですが、ほとんどの人はそのパターンのポイントを完全に見逃しており、ビューとビューモデルしか持っていません。 MVCのモデルは、MVVMのモデルと似ています。

MVCでは、プロセスは3つの異なる責任に分けられます。

  • ビューはユーザーにデータを提示する責任があります。
  • コントローラはページフローを担当します
  • モデルはビジネスロジックを担当します

MVCはWebアプリケーションにはあまり適していません。これは、デスクトップアプリケーションを作成するためにSmalltalkによって導入されたパターンです。 Web環境はまったく異なる動作をします。デスクトップ開発から40年前のコンセプトをコピーしてWeb環境に貼り付けるのは、あまり意味がありません。しかし、多くの人がこれは問題ないと考えています。なぜなら、彼らのアプリケーションはコンパイルして正しい値を返すからです。つまり、私の考えでは、特定の設計上の選択を問題ないと宣言するだけでは不十分です。

Webアプリケーションのモデルの例は次のとおりです。

public class LoginModel
{
    private readonly AuthenticationService authentication;

    public LoginModel(AuthenticationService authentication)
    {
        this.authentication = authentication;
    }

    public bool Login()
    {
        return authentication.Login(Username, Password);
    }

    public string Username { get; set; }
    public string Password { get; set; }
}

コントローラはこれを次のように使用できます。

public class LoginController
{
    [HttpPost]
    public ActionResult Login(LoginModel model)
    {
        bool success = model.Login();

        if (success)
        {
            return new RedirectResult("/dashboard");
        }
        else
        {
            TempData["message"] = "Invalid username and/or password";
            return new RedirectResult("/login");
        }
    }
}

あなたのコントローラメソッドとあなたのモデルは小さくて、簡単にテスト可能で要点になります。

11
Jeroen

大きな例がたくさんありますが、はっきりとしたクリスピーな方法で説明させてください。

ViewModel =ビューを提供するために作成されたモデル。

ASP.NET MVCビューには複数のモデルを含めることができないため、複数のモデルのプロパティをビューに表示する必要がある場合は不可能です。 ViewModelはこの目的を果たします。

View Modelは、ビューに必要なプロパティのみを保持できるモデルクラスです。データベースの複数のエンティティ(テーブル)のプロパティも含めることができます。名前が示すように、このモデルはビューの要件に合わせて作成されています。

以下にビューモデルの例をいくつか示します。

  • ビューページに複数のエンティティからのデータを一覧表示するには、ビューモデルを作成し、データを一覧表示するすべてのエンティティのプロパティを設定します。これらのデータベースエンティティを結合してビューモデルのプロパティを設定し、ビューに戻ってさまざまなエンティティのデータを1つの表形式で表示します。
  • ビューモデルは、ビューに必要な単一のエンティティの特定のフィールドのみを定義できます。

ViewModelを使用してレコードを複数のエンティティに挿入、更新することもできますが、ViewModelの主な用途は、複数のエンティティ(モデル)の列を単一のビューに表示することです。

ViewModelの作成方法はModelの作成と同じです。Viewmodelのビューの作成方法はModelのビューの作成と同じです。

これは ViewModelを使ってデータをリストする の小さな例です。

これが役に立つことを願っています。

10
Sheo Narayan

ビューモデルaは、複数のクラスプロパティを含むことができる単純なクラスです。必要なプロパティをすべて継承するためにそれを使います。 StudentとSubjectの2つのクラスがあります。

Public class Student
{
public int Id {get; set;}
public string Name {get; set;}
}  
Public class Subject
{
public int SubjectID {get; set;}
public string SubjectName {get; set;}
}

今度は(MVCでは)レコードに学生の名前と件名を表示したいのですが、次のようなクラスを複数追加することはできません。

 @model ProjectName.Model.Student  
 @model ProjectName.Model.Subject

上記のコードはエラーをスローします...

今私達は1つのクラスを作成し、それに任意の名前を付けることができますが、このフォーマット "XyzViewModel"はそれを理解するのをより簡単にします。継承の概念です。今度は、次の名前で3番目のクラスを作成します。

public class StudentViewModel:Subject
{
public int ID {get; set;}
public string Name {get; set;}
}

今度はこのViewModelをViewで使用します。

@model ProjectName.Model.StudentViewModel

これで、ViewのStudentViewModelおよび継承クラスのすべてのプロパティにアクセスできます。

10
Mayank

ViewModelは、MVCフレームワークの概念的な不器用さを修正するための回避策です。これは、3層のModel-View-Controllerアーキテクチャの4番目の層を表します。 Model(ドメインモデル)が適切ではない場合、Viewには大きすぎる(2〜3フィールドよりも大きい)場合は、Viewに渡すために小さいViewModelを作成します。

6
gsivanov
  • ViewModelはビューで表されるフィールドを含みます(LabelFor、EditorFor、DisplayForヘルパーのために)
  • ViewModelは、データ注釈またはIDataErrorInfoを使用して特定の検証規則を設定できます。
  • ViewModelは、異なるデータモデルまたはデータソースからの複数のエンティティまたはオブジェクトを持つことができます。

ViewModelをデザインする

public class UserLoginViewModel 
{ 
[Required(ErrorMessage = "Please enter your username")] 
[Display(Name = "User Name")]
[MaxLength(50)]
public string UserName { get; set; }
 [Required(ErrorMessage = "Please enter your password")]
 [Display(Name = "Password")]
 [MaxLength(50)]
 public string Password { get; set; } 
} 

ビューにビューモデルを表示する

@model MyModels.UserLoginViewModel 
@{
 ViewBag.Title = "User Login";
 Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<div class="editor-label">
 @Html.LabelFor(m => m.UserName)
</div>
<div class="editor-field">
 @Html.TextBoxFor(m => m.UserName)
 @Html.ValidationMessageFor(m => m.UserName)
</div>
<div class="editor-label">
 @Html.LabelFor(m => m.Password)
</div>
<div class="editor-field">
 @Html.PasswordFor(m => m.Password)
 @Html.ValidationMessageFor(m => m.Password)
</div>
<p>
 <input type="submit" value="Log In" />
</p>
</div>
}

行動を起こす

public ActionResult Login()
{ 
return View();
}
[HttpPost]
public ActionResult Login(UserLoginViewModel user)
{
// To acces data using LINQ
DataClassesDataContext mobjentity = new DataClassesDataContext();
 if (ModelState.IsValid) 
{ 
try
 {
 var q = mobjentity.tblUsers.Where(m => m.UserName == user.UserName && m.Password == user.Password).ToList(); 
 if (q.Count > 0) 
 { 
 return RedirectToAction("MyAccount");
 }
 else
 {
 ModelState.AddModelError("", "The user name or password provided is incorrect.");
 }
 }
 catch (Exception ex)
 {
 } 
 } 
 return View(user);
} 
  1. ViewModelでは、ビュー/ページに表示したいフィールド/データのみを配置します。
  2. ビューはViewModelのプロパティを繰り返しているので、レンダリングとメンテナンスは簡単です。
  3. ViewModelが複雑になったときはマッパーを使用してください。
1
wild coder

ビューモデルはデータの概念モデルです。その用途は、例えば、サブセットを取得するか、または異なるテーブルからデータを組み合わせることです。

特定のプロパティのみが必要な場合もあります。そのため、追加の不要なプロパティではなく、それらのプロパティのみをロードできます。

1
user6685907

View Modelは、View上でデータをレンダリングするために使用できるクラスです。 PlaceとPlaceCategoryという2つのエンティティがあり、1つのモデルを使用して両方のエンティティからデータにアクセスしたい場合、ViewModelを使用します。

  public class Place
    {
       public int PlaceId { get; set; }
        public string PlaceName { get; set; }
        public string Latitude { get; set; }
        public string Longitude { get; set; }
        public string BestTime { get; set; }
    }
    public class Category
    {
        public int ID { get; set; }
        public int? PlaceId { get; set; }
        public string PlaceCategoryName { get; set; }
        public string PlaceCategoryType { get; set; }
    }
    public class PlaceCategoryviewModel
    {
        public string PlaceName { get; set; }
        public string BestTime { get; set; }
        public string PlaceCategoryName { get; set; }
        public string PlaceCategoryType { get; set; }
    }

したがって、上記の例ではPlaceとCategoryは2つの異なるエンティティであり、PlaceCategory viewmodelはViewModelであり、これをViewで使用できます。

0
Sagar Shinde