3

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

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

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

我知道并非所有视图都一定有一个动作,并且并非所有动作都一定会返回一个视图,因此这可能会被证明是一个问题。

更新:

也许是这样的:

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

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

4

2 回答 2

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;
}
于 2012-07-23T00:44:58.177 回答
1

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

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

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

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

于 2012-07-23T00:24:00.460 回答