사전에 전달 된 모델 항목의 유형은 ..이지만이 사전에는 유형의 모델 항목이 필요합니다.

c# asp.net-mvc


이 질문과 커뮤니티 위키 답변은 이 메타 포스트 에서 논의 된 바와 같이 답변되지 않은 수많은 질문을 해결하는 데 도움이되도록 추가되었습니다 .


코드가 있는데 실행할 때 예외를 발생시킵니다.

사전에 전달 된 모델 항목은 Bar 유형이지만이 사전에는 Foo 유형의 모델 항목이 필요합니다.

이것은 무엇을 의미하며 어떻게 수정합니까?




Answer 1 Stephen Muecke


이 오류는 @model Foo 를 사용하여 모델이 typeof 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())

레이아웃에서 모델 선언

배치 파일에 모형 선언이 포함 된 경우 해당 배치를 사용하는 모든 뷰는 동일한 모형 또는 해당 모형에서 파생 된 모형을 선언해야합니다.

Layout에 별도의 모델에 대한 html을 포함하려면 Layout에서 @Html.Action(...) 을 사용하여 [ChildActionOnly] 메서드 를 호출하여 해당 모델을 초기화하고 모델에 대한 부분 뷰를 반환합니다.




Answer 2 Hooman Bahreini


이 질문에는 이미 큰 대답이 있지만 다른 시나리오 에서 EditorTemplate에 List 표시와 같은 오류가 발생 했습니다 .

나는 이런 모델을 가지고있다 :

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)

그리고 이것은 내 Bar 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>



Answer 3 CelzioBR


보기에 필요한 모델이 있는지 확인하십시오.

View

@model IEnumerable<WFAccess.Models.ViewModels.SiteViewModel>

<div class="row">
    <table class="table table-striped table-hover table-width-custom">
        <thead>
            <tr>
....

Controller

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

제 경우에는 부분 뷰를 사용하지만 일반 뷰에서 실행됩니다.