视图中的Asp.Net MVC Cast模型

问题描述

我有三种模型:动物,狗和猫。

动物分类

public class Animal
{
    
}

班犬

public class Dog : Animal
{
    
}

和猫类

public class Dog : Animal
{
    
}

还有两个控制器(DogController和CatController),每个控制器中都有一个index操作,该操作返回视图以显示列表结果。

狗控制器

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


}

狗的索引视图

@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>

在Dog Controller的索引动作中,返回类型为IList<Animal>,索引视图中的模型类型为IEnumerable<Dog>。 执行该应用程序时,会生成错误

在处理请求时发生未处理的异常。 InvalidOperationException:传递到ViewDataDictionary中的模型项的类型为'System.Collections.Generic.List 1[Animal]',but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IEnumerable 1 [Dog]'。

因此,将控制器中的动作发送的动物列表强制转换为视图中模型的Dogs类型列表非常重要。 如何在视图中将动物列表转换为狗列表,@ model IEnumerable为IEnumerable不起作用。

发布后动作中的同一件事,我们如何在操作中将Dog模型从视图转换为Animal模型

解决方法

多态似乎不适用于页面模型。您可以为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>

部分视图(_DogPartial):

@model Dog
<tr>
    <td>
        @Html.DisplayFor(modelItem => Model.Dog_ID)
    </td>
    <td>
        @Html.DisplayFor(modelItem => Model.Dog_Name)
    </td>
</tr>