【问题标题】:ASP.NET MVC3 Physical Location of View from controller来自控制器的 ASP.NET MVC3 视图的物理位置
【发布时间】:2012-04-12 17:28:54
【问题描述】:

从动作内部获取将由 MVC 动作提供服务的视图的物理位置的正确方法是什么?

我需要文件的最后修改时间来发送响应头。

【问题讨论】:

  • 注意,这个问题并没有欺骗stackoverflow.com/questions/4135450/…那个问题是关于在视图内部而不是在控制器内部。
  • 我可能是错的,但直到动作后执行或 OnActionExecuted 才可用。我想你可以遍历所有注册的 ViewEngines 并尝试根据 ViewLocation 集合查找视图,但这都是手动的
  • 也不欺骗stackoverflow.com/questions/1529417/…这个问题可能是针对MVC1的,Request.PhysicalPath返回一个无效的文件位置,它只是把我的路由当作文件请求。

标签: asp.net-mvc-3 views filepath


【解决方案1】:

获取视图物理位置的正确方法是映射其虚拟路径。可以从BuildManagerCompiledViewViewPath 属性检索虚拟路径(RazorView 派生自该类,因此您的IView 实例通常具有该属性)。

这是一个你可以使用的扩展方法:

public static class PhysicalViewPathExtension
{
    public static string GetPhysicalViewPath(this ControllerBase controller, string viewName = null)
    {
        if (controller == null)
        {
            throw new ArgumentNullException("controller");
        }

        ControllerContext context = controller.ControllerContext;

        if (string.IsNullOrEmpty(viewName))
        {
            viewName = context.RouteData.GetRequiredString("action");
        }

        var result = ViewEngines.Engines.FindView(context, viewName, null);
        BuildManagerCompiledView compiledView = result.View as BuildManagerCompiledView;

        if (compiledView != null)
        {
            string virtualPath = compiledView.ViewPath;
            return context.HttpContext.Server.MapPath(virtualPath);
        }
        else
        {
            return null;
        }
    }
}

像这样使用它:

public ActionResult Index()
{
    string physicalPath = this.GetPhysicalViewPath();
    ViewData["PhysicalPath"] = physicalPath;
    return View();
}

或:

public ActionResult MyAction()
{
    string physicalPath = this.GetPhysicalViewPath("MyView");
    ViewData["PhysicalPath"] = physicalPath;
    return View("MyView");
}

【讨论】:

  • 调用ViewEngines.Engines.FindView 需要做多少工作,所以我可以得到这个答案而无需实际执行结果?
  • 那应该不会很贵。您不打算执行视图吗?
  • @ChrisMarisic 我已经更新了我的答案。它现在展示了如何使用相同的方法但不执行视图。
  • 我也在看类似的东西,但是你的扩展方法是一个非常干净的用法。我正在使用路径来查找要用作 304 未修改计算的一部分的视图的最后修改时间。
  • @ChrisMarisic 太棒了!请记住,视图呈现的任何动态数据都可能会给您带来此类计算的问题。
【解决方案2】:

这可行:

private DateTime? GetDate(string controller, string viewName)
{
    var context = new ControllerContext(Request.RequestContext, this);
    context.RouteData.Values["controller"] = controller;
    var view = ViewEngines.Engines.FindView(context, viewName, null).View as BuildManagerCompiledView;
    var path = view == null ? null : view.ViewPath;
    return path == null ? (DateTime?) null : System.IO.File.GetLastWriteTime(path);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    相关资源
    最近更新 更多