이 질문 및 커뮤니티 위키 답변은 이 메타 게시물 에서 논의 된대로 답변되지 않은 수많은 질문을 종료하는 데 도움이되도록 추가되었습니다 .
일부 코드가 있으며 실행되면 다음과 같은 예외가 발생합니다.
사전에 전달 된 모델 항목은 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);
기본보기로 올바른 모델을 반환합니다. 그러나 뷰에 다음이 포함되면 예외가 throw됩니다.
@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 일 때 부분보기에 의도적으로 null 모델을 보내려면 다음 과 같이 할 수 있습니다. @Html.Partial("_Bar", Model.MyBar, new System.Web.Mvc.ViewDataDictionary())
Source : 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)
그리고 이것은 나의 바 EditorTemplate ( 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
입니다. 따라서 컬렉션을 전달하면 컬렉션의 각 항목에 대해 편집기 템플릿이 한 번씩 표시됩니다.
이 문제를 해결 한 방법입니다.
스타일을 편집기 템플릿 외부 및 기본보기 로 가져 왔습니다. .
@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
그래서 단지 수표의 일