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


84

이 질문 및 커뮤니티 위키 답변은 이 메타 게시물 에서 논의 된대로 답변되지 않은 수많은 질문을 종료하는 데 도움이되도록 추가되었습니다 .


일부 코드가 있으며 실행되면 다음과 같은 예외가 발생합니다.

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

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


1
사용할 때이 오류가있어 return View대신 return PartialView그래서 단지 수표의 일
리처드 Housham

답변:


91

이 오류는 모델이 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부분보기 로 전달합니다 . 또한의 값 MyBarnull(초기화되지 않은) 경우 기본적으로 Foo부분에 전달됩니다.이 경우에는

@Html.Partial("_Bar", new Bar())

레이아웃에서 모델 선언

레이아웃 파일에 모델 선언이 포함 된 경우 해당 레이아웃을 사용하는 모든 뷰는 동일한 모델 또는 해당 모델에서 파생 된 모델을 선언해야합니다.

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


26
+1에 대해 "MyBar의 값이 null (초기화되지 않은 경우)이면 기본적으로 Foo가 부분으로 전달됩니다.이 경우 반드시 있어야합니다." 매우 중요한 메모입니다.
Smix

모델 유형이 정의되지 않은 레이아웃 내에서 부분보기를 사용하면 동일한 오류가 발생합니다. Partial View는 정의되거나 필요하지 않은 경우 인덱스 페이지에서 모델을 수신하기 때문에 충돌하며, 부분 모델을 IndexModel로 설정하면 ViewData 속성이 null! ?? 이 시나리오를 수정하는 방법은 무엇입니까? 부분을 ​​레이아웃으로 이동해도 작동하지만 작동 방식을 이해하고 싶습니다.
Etienne Charland

부분보기가 "@model"없이 맨 위에 "@page"가있을 때 동일한 오류가 발생했습니다. "@page"를 제거하면 문제가 해결되었습니다.
EKanadily

1
Model.MyBarnull 일 때 부분보기에 의도적으로 null 모델을 보내려면 다음 과 같이 할 수 있습니다. @Html.Partial("_Bar", Model.MyBar, new System.Web.Mvc.ViewDataDictionary()) Source : https://stackoverflow.com/a/713921/4888725
Kirk Grover

6

이 질문에는 이미 훌륭한 대답이 있지만 다른 시나리오에서 동일한 오류가 발생 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>

1
대단해, 당신은 내 머리를 긁적 거리며 30 분 만에 날 구해 줬어. ASP.NET Core 3.1 MVC에서도 작동합니다.
Uwe Keim

5

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

전망

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

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


1
이것이 질문과 무슨 관련이 있습니까?

2
@StephenMuecke this champs-사전에 전달 된 모델 항목은 Bar 유형이지만이 사전에는 Foo
CelzioBR
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.