传入字典的模型项类型为.但是这本字典需要一个类型的模型项
本文关键字:模型 类型 字典 一个 | 更新日期: 2023-09-27 18:15:50
这个问题和社区wiki的答案已经被添加,以帮助关闭在这篇元文章中讨论的许多未解决的问题。
我有一些代码,当它执行时,它抛出一个异常说:
传入字典的模型项是Bar类型的,但是这个字典需要一个Foo类型的模型项
这是什么意思,我如何修复它?
这个错误意味着你正在导航到一个视图,它的模型被声明为Foo
的类型(通过使用@model Foo
),但你实际上传递给它一个模型是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())
在布局中声明模型
如果一个布局文件包含一个模型声明,那么所有使用该布局的视图必须声明相同的模型,或者从该模型派生的模型。
如果您想在布局中包含单独模型的html,那么在布局中,使用@Html.Action(...)
调用[ChildActionOnly]
方法初始化该模型并返回它的部分视图
这个问题已经有了很好的答案,但是我在不同的场景中遇到了同样的错误:在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(酒吧)
这个错误的原因是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>
观察视图是否具有所需的模型:
<<p> 视图/strong>@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);
}
在我的例子中,我使用了一个局部视图,但在正常视图中运行
考虑Partials/Map.cshtml
的部分map.cshtml
。这可以从要呈现部分的页面调用,只需使用<partial>
标记:
<partial name="Partials/Map" model="new Pages.Partials.MapModel()" />
这是我遇到的最简单的方法之一(尽管我使用razor页面,我相信MVC也是如此)
首先,您需要向列表视图返回一个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);
将从控制器方法填充的模型值传递给视图
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);
}
还有一件事如果您的视图是部分/子页面,并且该部分视图的模型由于某些原因(例如没有数据)为空,您将得到此错误。只需要处理null部分视图模型