私は 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
したがって、検証はとに対してのみ行われますLastName
。FluentValidation次のような検証が行われる可能性があります。
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 に含まれているからです。たとえば、次のようになります。Id
Id
http://www.yourwebsite.com/Employee/Edit/3
これをId
、名と姓の値とともにリポジトリ レイヤーに渡します。
レコードを削除するときは、通常、編集ビュー モデルと同じパスに従います。次の例のように、URL も存在します。
http://www.yourwebsite.com/Employee/Delete/3
ビューが初めて読み込まれるときに、Id
3 を使用してデータベースから従業員のデータを取得します。次に、ビュー/ページに静的テキストを表示して、どの従業員が削除されるかをユーザーが確認できるようにします。ユーザーが [削除] ボタンをクリックすると、Id
3 という値を使用して、それをリポジトリ レイヤーに渡します。Id
テーブルからレコードを削除するには、 のみが必要です。
もう 1 つのポイントは、すべてのアクションにビュー モデルが実際に必要なわけではないということです。単純なデータであれば、 のみを使用するのが適切ですEmployeeViewModel
。複雑なビュー/ページで、それぞれが異なる場合は、それぞれに個別のビュー モデルを使用することをお勧めします。
これで、ビュー モデルとドメイン モデルに関する混乱が解消されることを願っています。