この質問とコミュニティウィキの回答は、このメタ投稿で説明されているように、多数の未回答の質問を閉じるのに役立つように追加されました。
私はいくつかのコードを持っています、そしてそれが実行されるとき、それは言う例外を投げます:
ディクショナリに渡されるモデルアイテムはタイプBarですが、このディクショナリにはタイプFooのモデルアイテムが必要です。
これはどういう意味ですか、どうすれば修正できますか?
回答:
このエラーは、モデルがtypeofとして宣言されているビューにFoo
(を使用して@model Foo
)ナビゲートしているが、実際にはtypeofであるモデルを渡したことを意味します(モデルはビューに渡されるため、辞書Bar
という用語が使用されていることに注意してください) 。ViewDataDictionary
エラーの原因は次のとおりです
コントローラメソッドからビュー(または部分ビュー)に間違ったモデルを渡す
一般的な例には、匿名オブジェクト(または匿名オブジェクトのコレクション)を作成するクエリを使用して、それをビューに渡すことが含まれます
var model = db.Foos.Select(x => new
{
ID = x.ID,
Name = x.Name
};
return View(model); // passes an anonymous object to a view declared with @model Foo
または、オブジェクトのコレクションを、単一のオブジェクトを期待するビューに渡す
var model = db.Foos.Where(x => x.ID == id);
return View(model); // passes IEnumerable<Foo> to a view declared with @model Foo
エラーは、を使用するのではなく、ビュー内のモデルと一致するようにコントローラーでモデルタイプを明示的に宣言することにより、コンパイル時に簡単に識別できますvar
。
ビューから部分ビューに間違ったモデルを渡す
次のモデルが与えられた
public class Foo
{
public Bar MyBar { get; set; }
}
で宣言されたメインビューとで宣言され@model Foo
た部分ビュー@model Bar
、
Foo model = db.Foos.Where(x => x.ID == id).Include(x => x.Bar).FirstOrDefault();
return View(model);
正しいモデルがメインビューに戻ります。ただし、ビューに含まれている場合は例外がスローされます
@Html.Partial("_Bar") // or @{ Html.RenderPartial("_Bar"); }
デフォルトでは、部分ビューに渡されるモデルはメインビューで宣言されたモデルであり、使用する必要があります
@Html.Partial("_Bar", Model.MyBar) // or @{ Html.RenderPartial("_Bar", Model.MyBar); }
のインスタンスをBar
部分ビューに渡します。の値MyBar
がnull
(初期化されていない)の場合、デフォルトでFoo
パーシャルに渡されることにも注意してください。この場合、次のようにする必要があります。
@Html.Partial("_Bar", new Bar())
レイアウトでモデルを宣言する
レイアウトファイルにモデル宣言が含まれている場合、そのレイアウトを使用するすべてのビューは、同じモデル、またはそのモデルから派生したモデルを宣言する必要があります。
別のモデルのhtmlをレイアウトに含め、次にレイアウトに含める場合は、を使用@Html.Action(...)
して[ChildActionOnly]
メソッドを呼び出し、そのモデルを初期化し、そのモデルの部分ビューを返します。
Model.MyBar
nullがある、あなたはこれを行うことができます。 @Html.Partial("_Bar", Model.MyBar, new System.Web.Mvc.ViewDataDictionary())
出典:https://stackoverflow.com/a/713921/4888725
この質問にはすでにすばらしい答えがありますが、別のシナリオで同じエラーが発生しList
ました。EditorTemplateにを表示することです。
私はこのようなモデルを持っています:
public class Foo
{
public string FooName { get; set; }
public List<Bar> Bars { get; set; }
}
public class Bar
{
public string BarName { get; set; }
}
そしてこれが私の主な見解です:
@model Foo
@Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
@Html.EditorFor(m => m.Bars)
そしてこれは私のBarEditorTemplate(Bar.cshtml)です
@model List<Bar>
<div class="some-style">
@foreach (var item in Model)
{
<label>@item.BarName</label>
}
</div>
そして、私はこのエラーを受け取りました:
ディクショナリに渡されるモデルアイテムのタイプは「Bar」ですが、このディクショナリにはタイプ「System.Collections.Generic.List`1 [Bar]」のモデルアイテムが必要です。
このエラーの理由は、EditorFor
すでに反復処理されているList
ため、コレクションを渡すと、コレクション内のアイテムごとにエディターテンプレートが1回表示されるためです。
これが私がこの問題を修正した方法です:
エディターテンプレートの外に、スタイルを持ち込みました メインビューに:
@model Foo
@Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
<div class="some-style">
@Html.EditorFor(m => m.Bars)
</div>
そして、EditorTemplate(Bar.cshtml)を次のように変更しました。
@model Bar
<label>@Model.BarName</label>
ビューに必要なモデルがあるかどうかを確認します。
見る
@model IEnumerable<WFAccess.Models.ViewModels.SiteViewModel>
<div class="row">
<table class="table table-striped table-hover table-width-custom">
<thead>
<tr>
....
コントローラ
[HttpGet]
public ActionResult ListItems()
{
SiteStore site = new SiteStore();
site.GetSites();
IEnumerable<SiteViewModel> sites =
site.SitesList.Select(s => new SiteViewModel
{
Id = s.Id,
Type = s.Type
});
return PartialView("_ListItems", sites);
}
私の場合、部分ビューを使用しますが、通常のビューで実行されます
return View
代わりに使用するとこのエラーが発生したreturn PartialView
ので、確認するだけです