WPF/Silverlight を使用した MVVM にはかなり慣れていますが、これは MVC Web アプリケーションでの初めての試みです。
Entity Framework モデル (読み取り/書き込みアクションとビューを生成するテンプレート) の「サイト」モデル クラスから自動生成された TestSitesController というコントローラーを作成しました。私が変更した唯一のことは、いくつかのメソッドで Guid id = null のデフォルト パラメータがあった 3 つの場所でした。「= null」を削除しただけで、すべて正常に機能します。これが私が変更したものの例です
public ActionResult Delete(Guid id = null)
{
//....
}
これはに変更されました
public ActionResult Delete(Guid id)
{
//....
}
サイト モデルは、特別な SiteId、Abbreviation、および DisplayName ではありません。この質問では、できるだけ単純にしようとしています。わかりましたので、ウェブサイトを実行して htpp://.../TestSites/ に移動すると、すべてが完全に機能します。
すべてのビュー (作成、削除、詳細、および編集) が @model MVCWeb.MyEntities.Site を使用していることに気付きました。しかし、Index.cshtmlビューで、それが使用していることに気付きました
@model IEnumerable<MVCWeb.MyEntities.Site>
これは、生成されたテンプレートでは問題なく機能しますが、「複合ビュー モデル」を使用したいと思います。これは、MVVM の知識を混ぜようとしているところですが、可能であればそれに固執したいと考えています。私の考えでは、複合ビュー モデルは、1 つ以上のエンティティ モデルと SelectedSiteId などの追加のプロパティで構成されるビューに固有の単なるモデルです。
そこで、TestSitesViewModel という非常に単純な ViewModel を作成しました。
public class TestSitesViewModel
{
//Eventually this will be added to a base ViewModel to get rid
//of the ViewBag dependencies
[Display(Name = "Web Page Title")]
public string WebPageTitle;
public IEnumerable<MVCWeb.MyEntities.Site> Sites;
//Other Entities, IEnumberables, or properties go here
//Not important for this example
}
次に、コントローラーに IndexWithViewModel というアクション メソッドを追加しました。
public ActionResult IndexWithViewModel()
{
var vm = new TestSitesViewModel();
vm.WebPageTitle = "Sites With Composite View Model";
vm.Sites = db.Sites.ToList();
return View(vm);
}
次に、Index.cshtml のコピーを作成し、新しい ActionResult メソッド名に合わせて IndexWithModel.cshtml という名前を付けました。のトップラインを変更しました
@model IEnumerable<MVCWeb.MyEntities.Site>
に
@model MVCWeb.Models.TestSitesViewModel
これをテーブル セクションの前に追加して、DisplayNameFor と DisplayFor をテストしました。
@Html.DisplayNameFor(model => model.WebPageTitle)
@Html.DisplayFor(model => model.WebPageTitle)
<br />
を変更しました
@foreach (var item in Model) {
に
@foreach (var item in Model.Sites) {
今のところ、すべてのテーブル ヘッダーを含む tr セクションをコメント アウトします。データ注釈の Display 属性に示されているように、@Html.DisplayNameFor が「Web ページ タイトル」を使用する代わりに「WebPageTitle」の変数名を表示していることを除いて、すべてが完全に機能します。
[Display(Name = "Web Page Title")]
public string WebPageTitle;
また、テーブル ヘッダー情報を含む tr セクションにコメントを戻すと、model.Sites.Abbreviation、model.Sites[0].Abbreviation、およびその他のさまざまな組み合わせを試しましたが、エラーが発生しました。
<tr>
<th>
@Html.DisplayNameFor(model => model.Abbreviation)
</th>
<th>
@Html.DisplayNameFor(model => model.DisplayName)
</th>
<th></th>
</tr>
そこで何を使えばいいの?サイトは元の Index.cshtml でモデルとして使用されたのとまったく同じタイプであるため、model.Sites.Abbreviation が機能しない理由はよくわかりません。