传入字典的模型项的类型为..,但是该字典需要类型为

问题描述 投票:0回答:8

已添加此问题和社区 wiki 答案,以帮助解决此元帖子中讨论的许多未解答的问题。


我有一些代码,当它执行时,它会抛出一个异常:

传入字典的模型项是 Bar 类型,但该字典需要 Foo 类型的模型项

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

c# asp.net-mvc
8个回答
112
投票

该错误意味着您正在导航到其模型被声明为 typeof

Foo
的视图(通过使用
@model Foo
),但实际上您向其传递了一个 typeof
Bar
的模型(注意术语 dictionary 是使用是因为模型通过
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]
方法初始化该模型并返回其部分视图。


10
投票

这个问题已经有了一个很好的答案,但我在不同的场景中遇到了同样的错误:在 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)

这是我的栏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[栏]


出现此错误的原因是

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>

7
投票

观察视图是否有需要的模型:

查看

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

在我的例子中,我使用部分视图,但在普通视图中运行


4
投票

考虑

map.cshtml
处的部分
Partials/Map.cshtml
。可以从要渲染部分的页面调用此方法,只需使用
<partial>
标签即可:

<partial name="Partials/Map" model="new Pages.Partials.MapModel()" />

这是我遇到的最简单的方法之一(虽然我使用的是 razor 页面,但我确信 MVC 也是如此)


0
投票

首先,您需要将模型的 IEnumerable 版本返回到列表视图。

@model IEnumerable<IdentityManager.Models.MerchantDetail>

其次,需要从数据库返回一个列表。我是通过 SQL Server 完成的,所以这是我可以使用的代码。

    public IActionResult Merchant_Boarding_List()
        List<MerchantDetail> merchList = new List<MerchantDetail>();
        var model = new MerchantDetail();

        try
        {
            using (var con = new SqlConnection(Common.DB_CONNECTION_STRING_BOARDING))
            {
                con.Open();
                using (var command = new SqlCommand("select * from MerchantDetail md where md.UserGUID = '" + UserGUID + "'", con))
                {
                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            model.biz_dbaBusinessName = reader["biz_dbaBusinessName"].ToString();
                            merchList.Add(model);
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
        }

        return View(merchList);

0
投票

将从控制器方法填充的模型值传递到视图

 public async Task<IActionResult> Index()
 {
   //Getting Data from Database
   var model= await _context.GetData();

   //Selecting Populated Data from the Model and passing to view
   return View(model.Value);
 }

0
投票

还有一件事。 如果您的视图是部分/子页面,并且该部分视图的模型由于某种原因(例如没有数据)为空,您将收到此错误。只需要处理 null 部分视图模型


0
投票

我遇到此错误的原因是我从另一个操作调用一个操作,而不是使用“return RedirectToAction”。

© www.soinside.com 2019 - 2024. All rights reserved.