ASP .NET MVC VirtualPathProvider

时间:2010-08-18 17:43:50

标签: asp.net asp.net-mvc asp.net-mvc-2 view virtualpathprovider

我正在编写一个VirtualPathProvider来动态加载我的MVC视图,这些视图位于不同的目录中。我成功拦截了MVC之前的调用(在FileExists中),但在我的VirtualPathProvider中,我得到了原始的,预先路由的URL,如:

~/Apps/Administration/Account/LogOn

就个人而言,我知道MVC会寻找

~/Apps/Administration/Views/Account/LogOn.aspx

我应该从

中读取文件内容
D:\SomeOtherNonWebRootDirectory\Apps\Administration\Views\Account\LogOn.aspx

但我宁愿不用硬编码逻辑来“添加名为Views的目录并将aspx添加到最后”。

这个逻辑存储在哪里,如何将其存入虚拟路径提供程序?

感谢。对不起,如果我不清楚的话。

3 个答案:

答案 0 :(得分:4)

被修改

您需要创建一个继承WebFormViewEngine的类并设置ViewLocationFormats属性(继承自VirtualPathProviderViewEngine)。

默认值可以在MVC源代码中找到:

public WebFormViewEngine() {
    MasterLocationFormats = new[] {
        "~/Views/{1}/{0}.master",
        "~/Views/Shared/{0}.master"
    };

    AreaMasterLocationFormats = new[] {
        "~/Areas/{2}/Views/{1}/{0}.master",
        "~/Areas/{2}/Views/Shared/{0}.master",
    };

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

    AreaViewLocationFormats = new[] {
        "~/Areas/{2}/Views/{1}/{0}.aspx",
        "~/Areas/{2}/Views/{1}/{0}.ascx",
        "~/Areas/{2}/Views/Shared/{0}.aspx",
        "~/Areas/{2}/Views/Shared/{0}.ascx",
    };

    PartialViewLocationFormats = ViewLocationFormats;
    AreaPartialViewLocationFormats = AreaViewLocationFormats;
}

然后,您应该清除ViewEngines.Engines集合并将ViewEngine实例添加到其中。

答案 1 :(得分:0)

正如上面提到的SLaks,您需要创建自定义视图引擎并在FindView方法中添加视图查找逻辑。

public class CustomViewEngine : VirtualPathProviderViewEngine

{

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)

    {
        //Set view path
        string viewPath = GetCurrentViewPath();

        //Set master path (if need be)
        string masterPath = GetCurrentMasterPath();

        return base.FindView(controllerContext, viewPath, masterPath, useCache);
    }

}

在Application_Start中,您可以像这样注册View Engine:

 ViewEngines.Engines.Clear();
 ViewEngines.Engines.Add(new CustomViewEngine());

答案 2 :(得分:0)

答案是MVC没有正确找到我的控制器。如果MVC实际上确实找到了你的控制器,那么VirtualPathProvider应该处理两个请求:

  1. 请求了真实网址的初始请求(即http://.../Account/LogOn)。

  2. 在1中的请求之后,后续的FileExists检查http://.../Views/Account/LogOn.aspx,返回false,调用FileExists。这实际上是返回aspx内容。