ASP.NET MVC VirtualPathProvider

ASP.NET MVC VirtualPathProvider,asp.net,asp.net-mvc,asp.net-mvc-2,view,virtualpathprovider,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:\SomeOtherNonWeb

我正在编写一个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添加到末尾”

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

谢谢。如果我不清楚,很抱歉。

您需要创建一个继承
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实例添加到其中。

如上所述,您需要创建一个自定义视图引擎,并在FindView方法中添加视图查找逻辑

public class CustomViewEngine : VirtualPathProviderViewEngine
{

}

在应用程序_Start中,您可以按如下方式注册视图引擎:

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

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

  • 具有请求的实际url的初始请求(即)

  • 在1中的请求之后,检查的后续文件存在。返回false调用FileExists。这实际上是重新播放aspx内容


  • 你能说得更具体些吗?谢谢,谢谢。我如何从这些格式字符串中获取信息,让我的VirtualPathProvider知道从何处读取文件?换句话说,如果我的VirtualPathProvider收到~/Apps/Administration/Account/LogOn请求,我如何使用上述信息来查找D:\SomeOtherPath\Apps\Administration\Views\Account\LogOn.aspx?这不应该发生。你的VPP还有其他要求吗?我不知道你在问什么。。。如果我在MVC之前注册VPP,它会收到所有请求。如果我在之后注册它,MVC首先处理请求。另外,请注意,我要从中读取的源目录不在实际web应用程序的基本目录中…具体地说,它位于zip文件中。在第一个目录(必须返回false以阻止IIS尝试将其作为静态文件而不是运行控制器操作)之后,使用“~/Views/Account/LogOn.aspx”调用FileExists和“/AppName/Views/Account/LogOn.aspx”-这两者都需要返回true。
     ViewEngines.Engines.Clear();
     ViewEngines.Engines.Add(new CustomViewEngine());