MVC の ViewModel とは何ですか? 質問する

MVC の ViewModel とは何ですか? 質問する

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

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

動作と説明についての良い例があればもっと良いでしょう。

ベストアンサー1

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ビューから設定されていない可能性があり、従業員テーブルによって自動生成される可能性があります。また、DateCreatedストアド プロシージャまたはアプリケーションのサービス レイヤーで設定されている可能性もあります。したがって、ビュー モデルではIdと はDateCreated必要ありません。従業員の詳細 (既にキャプチャされている従業員) を静的テキストとして表示する場合に、これらの 2 つのプロパティを表示することができます。

ビュー/ページを読み込むと、従業員コントローラーの create アクション メソッドによってこのビュー モデルのインスタンスが作成され、必要に応じてフィールドに値が入力され、このビュー モデルがビュー/ページに渡されます。

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 MVCと仮定Razor)。

@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>

FirstNameしたがって、検証はとに対してのみ行われますLastNameFluentValidation次のような検証が行われる可能性があります。

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");
     }
}

データ注釈を使用すると、次のようになります。

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 つの値/プロパティのみがあり、ドメイン オブジェクト内のすべてのプロパティは含まれません。

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

public int DepartmentId { get; set; }

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

従業員データ (データベースにすでに追加されている従業員) を編集する場合、上記の例とあまり変わりません。ビュー モデルを作成し、たとえば と呼びます。このビュー モデルには、名や姓など、編集するデータのみを含めます。データを編集し、[送信] ボタンをクリックします。フィールドEditEmployeeViewModelについてはあまり心配する必要はありません。値はおそらく URL に含まれているからです。たとえば、次のようになります。IdId

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

これをId、名と姓の値とともにリポジトリ レイヤーに渡します。

レコードを削除するときは、通常、編集ビュー モデルと同じパスに従います。次の例のように、URL も存在します。

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

ビューが初めて読み込まれるときに、Id3 を使用してデータベースから従業員のデータを取得します。次に、ビュー/ページに静的テキストを表示して、どの従業員が削除されるかをユーザーが確認できるようにします。ユーザーが [削除] ボタンをクリックすると、Id3 という値を使用して、それをリポジトリ レイヤーに渡します。Idテーブルからレコードを削除するには、 のみが必要です。

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

これで、ビュー モデルとドメイン モデルに関する混乱が解消されることを願っています。

おすすめ記事