【问题标题】:Map MVC View Route Values to physical path将 MVC 视图路由值映射到物理路径
【发布时间】:2012-07-21 05:35:18
【问题描述】:

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

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

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

我知道并不是所有的视图都一定有一个动作,也不是所有的动作都一定会返回一个视图,所以这可能是个问题。

更新:

可能是这样的:

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

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

【问题讨论】:

  • 我听不懂。 MVC 内置路由系统有什么问题?
  • 内置路由系统很好,但我需要将viewName/controller对转换回物理路径,以简化渲染部分视图的方法所采用的参数,而不是不必传递完整的物理路径,现在我可以传递 viewNamecontroller 名称。

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


【解决方案1】:

这是我的做法:

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

【讨论】:

  • 从未听说过.NullOrEmpty() 方法!
  • 只是string.IsNullOrEmpty的语法糖,它是一种扩展方法。
  • 这是一个隐藏得很好的知识。
【解决方案2】:

从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 的调用中指定视图名称,则不是)。您已经提到了其他几个假设

【讨论】:

  • 您假设该视图与您在此处发布的答案中的操作具有相同的名称:viewName = context.RouteData.GetActionString();
  • 这不是假设任何事情,这是 Mvc 自己的约定,如果你 return View() 你得到映射到所请求操作的视图,我需要类似的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-29
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
  • 2019-01-05
  • 2016-03-22
  • 1970-01-01
相关资源
最近更新 更多