Question

I would like to determine the view model type from a (strongly typed) ASP.NET MVC 4 View before the view is executed. My Controller logic enables me to determine the view name, and thus load the view programatically, however there doesn't appear to be anything to give a clue about the model type:

var res = ViewEngines.Engines.FindPartialView(this.ControllerContext, viewName);
if (res.View != null)
{
     Type modelType = res.View.GetType(); //returns System.Web.Mvc.RazorView 
     //...so it would be great to be able to do:
     modelType = res.View.GetModelType();//...but this does not exist
}

The reason I want to do this is because I am automatically mapping my domain models to view models - the request contains information from which I can derive the view name, but not the view model type, so I want to derive this from the view in order to do the model mapping.

Was it helpful?

Solution

This will do the trick (I verified this in a controller, but it can run in a filter as well).

** Note this works for the default view engine/default view page and might need tweaking otherwise, it's not hardened by any means, it's just to show the pattern

Type modelType = null;

var view = ViewEngines.Engines.FindView(this.ControllerContext, "Index", string.Empty);

var bmView = (BuildManagerCompiledView)view.View;

// this need caching, no reason to call build manager again and again.
var razorView = BuildManager.GetCompiledType(bmView.ViewPath);

// this doesn't allow for customizing the page type (but not a common scenario)
if (typeof(WebViewPage).IsAssignableFrom(razorView) && razorView.BaseType.IsGenericType)
{
    modelType = razorView.BaseType.GetGenericArguments()[0];
}

OTHER TIPS

You can do it like this:

//viewName can be "~/Views/Account/Login.cshtml"
var type = BuildManager.GetCompiledType(viewName); 
bool isGeneric = type.BaseType.IsGenericType;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top