'传入字典的模型项的类型为'对于继承的模型类

时间:2016-04-07 17:56:25

标签: c# asp.net-mvc inheritance asp.net-mvc-layout

我知道这个问题已被多次询问过,但我还没有找到一个已经提出的问题来解决我的问题。我的问题是,由于某种原因,我无法将继承自期望类型的类型用作模型。

我得到的确切错误是:

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开发的新手,所以如果有人知道更好的方法,那么评论会有所帮助:)

2 个答案:

答案 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>)的属性的接口可能会成为协变。