Reputation: 48476
Say I have a route value for a path that has a view, like
new
{
controller = "Home",
action = "Index"
}
How do I map this to ~/Views/Home/Index.cshtml
?
I know not all views necessarily have an action, and that not all actions necessarily return a view, so that might prove to be an issue.
Maybe something like this:
IView view = ViewEngines.Engines.FindView(ControllerContext, "Index").View;
view.GetViewPath();
But that allows me to specify a controller instead of assuming I want to use my controllerContext (or maybe even mocking up a controllerContext for the Controller (string) I want..
Upvotes: 3
Views: 2102
Reputation: 48476
Here's how I've done it:
private string GetPhysicalPath(string viewName, string controller)
{
ControllerContext context = CloneControllerContext();
if (!controller.NullOrEmpty())
{
context.RouteData.Values["controller"] = controller;
}
if (viewName.NullOrEmpty())
{
viewName = context.RouteData.GetActionString();
}
IView view = ViewEngines.Engines.FindView(viewName, context).View;
string physicalPath = view.GetViewPath();
return physicalPath;
}
and the extension method for GetViewPath
is:
public static string GetViewPath(this IView view)
{
BuildManagerCompiledView buildManagerCompiledView = view as BuildManagerCompiledView;
if (buildManagerCompiledView == null)
{
return null;
}
else
{
return buildManagerCompiledView.ViewPath;
}
}
and CloneControllerContext
is:
private ControllerContext CloneControllerContext()
{
ControllerContext context = new ControllerContext(Request.RequestContext, this);
return context;
}
Upvotes: 2
Reputation: 8595
From RazorViewEngine.cs (in the mvc3 source), the search paths for views are as follows (assuming razor):
ViewLocationFormats = new[] {
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
{1} refers to the controller routevalue, and {0} is the view name (not part of the routevalues).
You can search these locations to try to find a view which matches your criteria but you also need to understand quite how many assumptions you are making...i.e. that the view has the same name as the action (by default yes, but not if you specify a view name in the call to View in the controller's action). You've mentioned a couple of other assumptions already
Upvotes: 1