开发者

Can I refer to the type parameter in an MVC view?

Given a strongly typed view in ASP.Net MVC, is it possible to refer to the type parameter used to declare the view?

For example, if a page is declared as

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

is it possible to reference the type-parameter in ViewPage<TModel>?

I know I can do Model.GetType() but I have a situation where I have one view model derived from another, and both using the same view. I currently have a line like

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

to detect if the view is being used to display the derived model, but I'd like to be able to do it without hard-coding the typeof(...) call.

I want to do someth开发者_开发百科ing like Model.GetType().IsSubclassOf(typeof(TModel))


If you create your own base class you can expose the model type via a property:

public class BaseViewPage<TModel> : ViewPage<TModel>
{
    public Type ModelType { get { return typeof(TModel); } }
}

Change

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

to

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

The model type is exposed via this.ModelType


From the MSDN documentation on ViewPage(TModel):

Model - Gets the Model property of the associated ViewDataDictionary object.

Grabbing the type from the Model property vis Model.GetType() is no more expensive than TModel is typeof(X). As Giddy indicated, in his comment, there isn't real value in knowing the type of TModel as you will still have to make an if comparison.

That said I would be looking into your application architecture as there seems to be a code smell here. I am making an assumption, but it seems that you are utilizing the same view with two different models, but displaying different data depending on the model's type. To avoid issues like this I have my team follow the one model per view rule. This tends to keep your models and views succinct. Through effective use of partials you don't even feel the constraint.


This should give you an instance of the type object for TModel

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

.BaseType() is needed because 'this' actually corresponds to the class generated for your .aspx view by asp.net at runtime.

So this.GetType().BaseType should give you the type object for System.Web.Mvc.ViewPage

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜