传递到字典中的模型项的类型为..,但是此字典需要类型为的模型项


84

已添加此问题和社区Wiki答案,以帮助解决本元文章中讨论的许多未回答的问题。


我有一些代码,执行时会引发异常:

传递到字典中的模型项的类型为Bar,但此字典需要模型类型为Foo的项

这是什么意思,我该如何解决?


1
使用return View而不是时出现此错误,return PartialView因此需要检查一下
Richard Housham

Answers:


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

将正确的模型返回到主视图。但是,如果视图包含

@Html.Partial("_Bar") // or @{ Html.RenderPartial("_Bar"); }

默认情况下,传递给部分视图的模型是在主视图中声明的模型,您需要使用

@Html.Partial("_Bar", Model.MyBar) // or @{ Html.RenderPartial("_Bar", Model.MyBar); }

将的实例传递Bar到局部视图。还要注意,如果MyBaris的值null(尚未初始化),则默认情况下Foo将传递给part,在这种情况下,需要

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

在布局中声明模型

如果布局文件包含模型声明,则所有使用该布局的视图都必须声明相同的模型或从该模型派生的模型。

如果要在布局中包含单独模型的html,请在布局中使用@Html.Action(...)调用[ChildActionOnly]方法来初始化该模型并为其返回局部视图。


26
+1表示“还请注意,如果MyBar的值为null(尚未初始化),则默认情况下,Foo将传递给局部变量,在这种情况下,它必须为”。非常重要的说明。
混合

我在布局中有部分视图,但未定义模型类型,因此也遇到了相同的错误。Partial View崩溃是因为它在未定义也不需要时从索引页面接收模型,并且如果我将部分模型设置为IndexModel,则ViewData属性为null!如何解决这种情况?将部分移到布局中确实可以,但是我想了解它是如何工作的。
Etienne Charland

当我的局部视图的顶部没有“ @model”时,我遇到了相同的错误。删除“ @page”解决了问题。
EKanadily

1
如果您想在null时有意将null模型发送到部分视图,Model.MyBar则可以执行以下操作: @Html.Partial("_Bar", Model.MyBar, new System.Web.Mvc.ViewDataDictionary()) 来源:https
Kirk Grover

6

这个问题已经有了不错的答案,但是在不同的情况下,我遇到了相同的错误:ListEditorTemplate中显示

我有一个像这样的模型:

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 EditorTemplateBar.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>

并将EditorTemplateBar.cshtml)更改为此:

@model Bar

<label>@Model.BarName</label>

1
太棒了,半小时挠头后,您才救了我。也适用于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这个冠军-传递到字典中的模型项为Bar类型,但此字典需要模型为Foo的模型项
CelzioBR
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.