将MVC视图路由值映射到物理路径

时间:2012-07-22 23:24:35

标签: c# asp.net-mvc-3 routes asp.net-mvc-routing

假设我有一个有视图的路径的路由值,比如

new
{
    controller = "Home",
    action = "Index"
}

如何将此映射到~/Views/Home/Index.cshtml

我知道并非所有观点都必然会有一个行动,并且并非所有行动都必然会返回一个观点,因此这可能会成为一个问题。

更新

也许是这样的:

IView view = ViewEngines.Engines.FindView(ControllerContext, "Index").View;
view.GetViewPath();

但这允许我指定一个控制器,而不是假设我想使用我的controllerContext(或者甚至可能为我想要的Controller(字符串)模拟一个controllerContext ..

2 个答案:

答案 0 :(得分:2)

以下是我的表现:

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;
}

GetViewPath的扩展方法是:

public static string GetViewPath(this IView view)
{
    BuildManagerCompiledView buildManagerCompiledView = view as BuildManagerCompiledView;
    if (buildManagerCompiledView == null)
    {
        return null;
    }
    else
    {
        return buildManagerCompiledView.ViewPath;
    }
}

CloneControllerContext是:

private ControllerContext CloneControllerContext()
{
    ControllerContext context = new ControllerContext(Request.RequestContext, this);
    return context;
}

答案 1 :(得分:0)

从RazorViewEngine.cs(在mvc3源代码中),视图的搜索路径如下(假设是剃刀):

    ViewLocationFormats = new[] {
        "~/Views/{1}/{0}.cshtml",
        "~/Views/{1}/{0}.vbhtml",
        "~/Views/Shared/{0}.cshtml",
        "~/Views/Shared/{0}.vbhtml"
    };

{1}表示控制器路由值,{0}是视图名称(不是路由值的一部分)。

您可以搜索这些位置以尝试查找符合您标准的视图,但您还需要了解您正在做出多少假设...即。该视图与该操作具有相同的名称(默认为yes,但如果您在控制器操作中调用View中指定视图名称则不是)。你已经提到了其他一些假设