我可以在 MVC 视图中引用类型参数吗?

Posted

技术标签:

【中文标题】我可以在 MVC 视图中引用类型参数吗?【英文标题】:Can I refer to the type parameter in an MVC view? 【发布时间】:2011-03-29 04:01:10 【问题描述】:

给定 ASP.Net MVC 中的强类型视图,是否可以引用用于声明视图的类型参数?

例如,如果一个页面被声明为

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyProject.MyViewModel>" %>

是否可以引用ViewPage&lt;TModel&gt;中的类型参数?

我知道我可以做到Model.GetType(),但我有一个视图模型是从另一个视图模型派生的,并且两者都使用相同的视图。我目前有一条类似

的行
<% if (Model.GetType().IsSubclassOf(typeof(MyViewModel)))
    %>

检测视图是否用于显示派生模型,但我希望能够在不对typeof(...) 调用进行硬编码的情况下执行此操作。

我想做Model.GetType().IsSubclassOf(typeof(TModel))之类的事情

【问题讨论】:

如果没有硬编码MyViewModel,你会怎么做。即使您可以引用 Type 参数,您仍然会执行 if(TModel is typeof(MyViewModel)... 类似的操作。如果你真的想走这条路,你可以在变量Type 中传递你想要检查的类型。 @giddy:我想做一些类似 Model.GetType().IsSubclassOf(typeof(TModel)) 【参考方案1】:

如果您创建自己的基类,则可以通过属性公开模型类型:

public class BaseViewPage<TModel> : ViewPage<TModel>

    public Type ModelType  get  return typeof(TModel);  

改变

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyProject.MyViewModel>" %>

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="MyProject.BaseViewPage<MyProject.MyViewModel>" %>

模型类型通过 this.ModelType 公开

【讨论】:

优雅。我喜欢。谢谢。【参考方案2】:

来自ViewPage(TModel) 上的 MSDN 文档:

Model - 获取关联的 ViewDataDictionary 对象的 Model 属性。

从 Model 属性 vis Model.GetType() 中获取类型并不比 TModel is typeof(X) 贵。正如Giddy 在他的评论中指出的那样,知道 TModel 的类型并没有真正的价值,因为您仍然需要进行 if 比较。

也就是说,我会调查您的应用程序架构,因为这里似乎有代码异味。我在做一个假设,但您似乎正在使用具有两个不同模型的相同视图,但根据模型的类型显示不同的数据。为避免此类问题,我让我的团队关注one model per view rule。这往往会使您的模型和视图保持简洁。通过有效地使用分部,您甚至感觉不到约束。

【讨论】:

这是一个工作流应用程序,其中工作流的大多数步骤只需要接受/拒绝和一些 cmets,但有些需要输入额外的数据。我有一个适用于大多数情况的视图模型,以及具有附加数据的附加属性的派生模型。这使控制器保持清洁,因为工作流程的每个步骤都以相同的方式处理。视图只需要检测是否正在使用派生视图,然后调用关联的部分视图来呈现附加的表单字段。【参考方案3】:

这应该给你一个 TModel 类型对象的实例

this.GetType().BaseType.GetGenericArguments()[0]

.BaseType() 是必需的,因为“this”实际上对应于 asp.net 在运行时为您的 .aspx 视图生成的类。

所以 this.GetType().BaseType 应该为您提供 System.Web.Mvc.ViewPage 的类型对象

【讨论】:

+1 - 很好,很直接,但我认为马丁的胜利是基于优雅。还是谢谢。

以上是关于我可以在 MVC 视图中引用类型参数吗?的主要内容,如果未能解决你的问题,请参考以下文章

引用的 MIME 媒体类型参数是不是允许转义引号?

“类型 T 必须是引用类型才能将其用作参数”是啥意思?

C#在方法调用中,参数按值传递与按引用传递的区别是啥?

可以使用StringList类型的cloudformation SSM动态引用解析列表吗?

Drupal:我应该将视图添加为字段吗?

具有节点引用和 cck3 多组字段的 Drupal 视图