我知道这个问题已被多次询问过,但我还没有找到一个已经提出的问题来解决我的问题。我的问题是,由于某种原因,我无法将继承自期望类型的类型用作模型。
我得到的确切错误是:
The model item passed into the dictionary is of type 'ShoppingDealsClient.Models.ListViewModel`1[ShoppingDealsClient.Models.Deal]', but this dictionary requires a model item of type 'ShoppingDealsClient.Models.ListViewModel`1[ShoppingDealsClient.Models.BaseResponseModel]'.
每当我尝试访问页面http://localhost:50548/Home/Deal
时都会收到此错误。
让我们看一下Deal.cshtml
页面:
@{
ViewBag.Title = "Deals";
Layout = "~/Views/Shared/_ListLayout.cshtml";
}
它只是对_ListLayout.cshtml
:
<!DOCTYPE html>
@{
Layout = "~/Views/Shared/_MenuedLayout.cshtml";
}
@model ShoppingDealsClient.Models.ListViewModel<ShoppingDealsClient.Models.BaseResponseModel>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<h1>
<span>@ViewBag.Title</span>
<button class='btn btn-primary pull-right'>+ Add New</button>
</h1>
<div>
@RenderBody()
</div>
</body>
</html>
如您所见,_ListLayout.cshtml
页面需要ListViewModel<BaseResponseModel>
个对象作为其模型。
以下是我返回视图的代码:
public ActionResult Deal()
{
return View(new ListViewModel<Deal>());
}
其中Deal
继承自BaseResponseModel
。
正如您所看到的,我在Deal()
方法中返回了正确的类型,但我仍然遇到此类错误。我使用Layout
次观看会有问题吗?有没有更好的方法来使用可以接受模型的部分视图?
编辑我的继承
我打算重复使用同样的_ListLayout
来最终显示所有从BaseResponseModel
继承的不同模型的列表。这就是为什么我的继承是必要的。
我是MVC开发的新手,所以如果有人知道更好的方法,那么评论会有所帮助:)
答案 0 :(得分:1)
问题在于:
@model ShoppingDealsClient.Models.ListViewModel<ShoppingDealsClient.Models.BaseResponseModel>
您的视图需要上述类型的模型,并传递类型为ListViewModel<Deal>
的对象。
正如我可以从错误消息中推断,Deal
不是BaseResponseModel
。如果从Deal
继承BaseResponseModel
确实有意义,那么这样做可以解决您的问题。否则,您必须更改View所期望的模型,或者将传递给视图的模型更改为正确的模型。
答案 1 :(得分:1)
有很多的问题可以解决您的问题。要么你只是不认识它,要么那些答案不是你想要听到的。
ListViewModel<Deal>
不是ListViewModel<BaseResponseModel>
,因为BaseResponseModel
不是协变的。以同样的方式,Cage<Tiger>
不是Cage<Animal>
,因为您可以将Rabbit
添加到Cage<Animal>
但不是Cage<Tiger>
(至少没有可怕的结果) )。
对协方差进行一些研究,看看是否需要创建协变接口或找到解决问题的其他解决方案。
协变接口的exmnaple类似于:
public interface IBaseModel<out TModel> where TModel : TBaseResponseModel
约束是接口只能输出 TModel
个对象 - 它不能接受任何输入(并且不能具有任何协变属性,如List<TModel>
。
因此,具有get-only属性和/或返回协变接口(如IEnumerable<TModel>
)的属性的接口可能会成为协变。