ASP .NET MVC VirtualPathProvider

发布于 2024-09-14 18:33:04 字数 538 浏览 3 评论 0原文

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

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

谢谢。抱歉,如果我没说清楚。

I am writing a VirtualPathProvider to dynamically load my MVC views, which are located in a different directory. I successfully intercept the call before MVC (in FileExists), but in my VirtualPathProvider, I get the raw, pre-routed url like:

~/Apps/Administration/Account/LogOn

Personally, I know that MVC will look for

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

and that I should be reading the file contents from

D:\SomeOtherNonWebRootDirectory\Apps\Administration\Views\Account\LogOn.aspx

but I'd rather not hard code the logic to "add the directory named Views and add aspx to the end".

Where is this logic stored and how can I get it into my virtual path provider?

Thanks. Sorry if I'm not being clear.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

生寂 2024-09-21 18:33:04

编辑

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

Edited

You need to make a class that inherits WebFormViewEngine and sets the ViewLocationFormats property (inherited from VirtualPathProviderViewEngine).

The default values can be found in the MVC source code:

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

You should then clear the ViewEngines.Engines collection and add your ViewEngine instance to it.

水溶 2024-09-21 18:33:04

正如上面的 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 中,您可以像这样注册您的视图引擎:

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

As SLaks mentioned above, you need to create a Custom View Engine and add your view-finding logic in the FindView method.

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

}

In the Application_Start, you can register your View Engine like this:

 ViewEngines.Engines.Clear();
 ViewEngines.Engines.Add(new CustomViewEngine());
滥情哥ㄟ 2024-09-21 18:33:04

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

  1. 带有所请求的实际 url 的初始请求(即 http://.../Account/LogOn)。

  2. 随后的 FileExists 检查 http://.../Views/Account/LogOn。 aspx,1.中的请求后调用FileExists返回false。这实际上会重新调整 aspx 内容。

The answer was that MVC was not finding my controller properly. If MVC does in fact find your controller properly, there should be two requests processed by the VirtualPathProvider:

  1. An initial request with the acutal url requested (ie. http://.../Account/LogOn).

  2. A subsequent FileExists check for http://.../Views/Account/LogOn.aspx, after the request in 1. returns false calling FileExists. This actually retuns the aspx content.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文