C# 视图中的Asp.NETMVC转换模型
我有三个模型:动物、狗和猫 类动物C# 视图中的Asp.NETMVC转换模型,c#,asp.net-mvc,asp.net-core,asp.net-mvc-4,asp.net-mvc-3,C#,Asp.net Mvc,Asp.net Core,Asp.net Mvc 4,Asp.net Mvc 3,我有三个模型:动物、狗和猫 类动物 public class Animal { } 班犬 public class Dog : Animal { } 和班猫 public class Dog : Animal { } 还有两个控制器(DogController和CatController),在每个控制器中,都有一个索引操作,返回视图以显示列表结果 狗控制器 public class DogController : Controller { public
public class Animal
{
}
班犬
public class Dog : Animal
{
}
和班猫
public class Dog : Animal
{
}
还有两个控制器(DogController和CatController),在每个控制器中,都有一个索引操作,返回视图以显示列表结果
狗控制器
public class DogController : Controller
{
public DogController ()
{
}
public async Task<IActionResult> Index()
{
DogRepository IRepos = new DogRepository ();
// Get List of Dogs
IList<Animal> listDogs= await IRepos.GetListDogs();
return View(ilIst);
}
[Httpost]
public async Task<IActionResult> Add(Animal Dog)
{
....
// Add dog to Database
return RedirectToAction("Index");
}
}
公共类控制器:控制器
{
公共控制器()
{
}
公共异步任务索引()
{
DogRepository IRepos=新的DogRepository();
//获取狗的列表
IList listDogs=等待IRepos.GetListDogs();
返回视图(ilIst);
}
[Httpost]
公共异步任务添加(动物狗)
{
....
//将狗添加到数据库
返回操作(“索引”);
}
}
狗的索引视图
@model IEnumerable<Dog>
@{
ViewData["Title"] = "Index";
}
<div class="row">
<div class="table-responsive">
<table class="table">
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Dog_ID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Dog_Name)
</td>
</tr>
}
</table>
</div>
</div>
@model IEnumerable
@{
ViewData[“标题”]=“索引”;
}
@foreach(模型中的var项目)
{
@DisplayFor(modeleItem=>item.Dog\u ID)
@DisplayFor(modelItem=>item.Dog\u Name)
}
在狗控制器的索引操作中,返回类型为IList
,索引视图中的模型类型为IEnumerable
。
执行应用程序时,会生成一个错误
处理请求时发生未处理的异常。
InvalidOperationException:传递到ViewDataDictionary的模型项的类型为“System.Collections.Generic.List1[Animal]”,但此ViewDataDictionary实例需要类型为“System.Collections.Generic.IEnumerable
1[Dog]”的模型项
因此,将控制器中的操作发送的动物列表强制转换为视图中模型的狗类型列表非常重要。
我们如何将动物列表转换为视图中的狗列表,@model IEnumerable as IEnumerable不起作用
在动作后,同样的事情,我们如何将狗模型从视图转换为动作中的动物模型多态性似乎不适用于页面模型。可以为Cat和Dog定义局部视图,为局部视图使用子类,并将基类用作主视图的模型 主视图(索引):
@model IEnumerable<Animal>
@{
ViewData["Title"] = "Index";
}
<div class="row">
<div class="table-responsive">
<table class="table">
<thead>
</thead>
<tbody>
@foreach (var item in Model)
{
@if (item is Dog)
{
<partial name="_DogPartial" model="item" />
}
}
</table>
</div>
</div>
@model Dog
<tr>
<td>
@Html.DisplayFor(modelItem => Model.Dog_ID)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Dog_Name)
</td>
</tr>
@model IEnumerable
@{
ViewData[“标题”]=“索引”;
}
@foreach(模型中的var项目)
{
@如果(项目是狗)
{
}
}
局部视图(\u dogportial):
@model IEnumerable<Animal>
@{
ViewData["Title"] = "Index";
}
<div class="row">
<div class="table-responsive">
<table class="table">
<thead>
</thead>
<tbody>
@foreach (var item in Model)
{
@if (item is Dog)
{
<partial name="_DogPartial" model="item" />
}
}
</table>
</div>
</div>
@model Dog
<tr>
<td>
@Html.DisplayFor(modelItem => Model.Dog_ID)
</td>
<td>
@Html.DisplayFor(modelItem => Model.Dog_Name)
</td>
</tr>
@模型狗
@DisplayFor(modelItem=>Model.Dog\u ID)
@DisplayFor(modelItem=>Model.Dog\u Name)
为什么listDogs
是IList
而不是IList
?你不应该仅仅改变变量的类型吗?除了上面的正确答案,我看到你正在使用一个名为DogRepository的额外类来包含你的逻辑。不要称它为IRepos,这是您将为接口命名的名称。考虑把它变成像仓库一样的东西,这样你就可以把代码通用化,实例化,比如仓库。您可以将此部分作为“作用域”服务的一部分,并通过依赖项注入将其添加到控制器中,这是避免代码重复的一种非常简洁的方法。我想使用父类来声明一个对象,然后我可以将子类的任何对象分配给它。例如,它可以用于接受参数的函数。该参数可以是父类类型,因此我们可以向该函数发送子类的任何对象。这就是我的例子,我声明了Aimal类型的对象,因此我可以给这个对象分配一只狗或一只猫。现在的问题是如何将此Animal类型的对象发送到接受Dog和Cat类型模型的视图。它会生成错误问题是Dogs视图中的模型比发送给它的集合类型更具体。如果在您的视图中更改为,它将接受狗或猫的集合,但模型将只识别基本类型中的字段,这可能不是您想要的。为狗或猫创建特定视图没有什么错,但您需要从控制器传递特定的集合。此外,请考虑传递一个DTO而不是实际的DB类型;当然,我认为多态性是从儿童类到母亲类,而不是从母亲类到儿童类。效果我必须将模型与我发送给它的狗或猫对象的动物类型放在一起