2

我想创建一个模块化的 ASP.NET 应用程序。就像,我有一个主应用程序,它只是某种模块加载器。它只有一个“Default.aspx”页面。并且,根据加载的模块,此页面将创建一个菜单和指向模块中的页面的链接。

我希望这些模块是打包到 dll 中的 ASP.NET 项目。因此,我想将该 dll 放入我的主应用程序的“模块”文件夹中,它将识别模块,并使用反射来加载模块,检查它们以找到页面,并从中构建一个菜单。

到目前为止我所做的:

在我的解决方案中,我有一个“DummyModule”项目。这个项目只有 3 页。没什么特别的。

我还有另一个名为“MainApp”的项目。这是“大事”。

在这个项目中,我有一个“ModuleLoader”类。当调用“LoadModules”方法时,它会在我的应用程序的“Modules”文件夹中搜索“dll”文件。并且,使用反射,加载这些模块。对于这些模块中的每一个,仍然使用反射,它搜索所有“页面”类型,并将名称存储到列表中。

在“Default.aspx”页面的“Page_Load”方法中,它调用“ModuleLoader”类,获取每个模块的所有模块名称和所有页面名称,并从中构建一个菜单。我创建了一个超链接模式,其中包含加载正确页面所需的所有信息。即:“/ModuleName/PageName”。我没有使用“aspx”扩展名。好的,到目前为止,一切都很好。

这是棘手的部分。

我创建了一个名为“PageLoaderModule”的 HTTPModule。该模块拦截所有请求,因此我可以读取 URL 以从我必须加载的模块中识别出哪个页面。

这正是我不能做的,我不知道如何解决这个问题。

我在做什么:

public class PageLoaderModule : IHttpModule
{
    #region IHttpModule Members

    public void Dispose()
    {
        //clean-up code here.
    }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += context_BeginRequest;
    }

    private void context_BeginRequest(object sender, EventArgs e)
    {
        var application = (HttpApplication)sender;

        if (Regex.IsMatch(application.Request.RawUrl, @"/.+/.+"))
        {
            var parts = application.Request.RawUrl.Split('/').Where(u => !string.IsNullOrWhiteSpace(u)).ToList();

            IHttpHandler page = ModuleManager.GetPage(parts[0], parts[1]);

            page.ProcessRequest(application.Context);
        }
    }

    #endregion IHttpModule Members
}

“GetPage”方法,在指定程序集中找到正确的“Page”类型,创建一个实例并返回那个 Page 实例。

但是当我调用 IHTTPHandler 接口的“ProcessRequest”方法时,它不会加载页面。

有可能这样做吗?有什么想法吗?

编辑:

我已经尝试过@Slavo 的建议。

在搜索 anwser 时,我找到并尝试了类似的解决方案,实现了我自己的 VirtualPathProvider 和 VirtualFile。它几乎奏效了。虚拟路径处理并加载正确的页面,但是,当页面加载时,我的浏览器中出现以下错误:

Parser Error Message: Could not load type 'DummyModule.Pages.DummyPage3'.
Source Error: 
Line 1: <% @ Page Language="C#" AutoEventWireup="true" CodeBehind="DummyPage3.aspx.cs" Inherits="DummyModule.Pages.DummyPage3" %>

所以,我不知道我是否做错了什么,或者这不是我正在寻找的解决方案。所以,我尝试了其他选择。

我正确地将“.aspx”文件的“构建操作”标记为“嵌入式资源”,因此它可以作为虚拟路径访问。但我仍然得到上面的错误。

4

2 回答 2

1

这看起来像是您想要编写一个VirtualPathProvider. 此类允许您控制为编译系统提供组件的逻辑。

当 ASP.NET 编译页面来处理请求时,默认情况下它只使用 ASPX 文件和代码隐藏。如果您编写 custom VirtualPathProvider,您将能够告诉它不这样做。因此,当 ASP.NET 需要为特定路径编译页面来处理请求时,您的提供程序可以从程序集中提取它。

这是一篇有用的文章:http: //support.microsoft.com/kb/910441

于 2013-10-03T15:17:04.197 回答
0

您应该PostMapRequestHandler在模块中处理事件并IHttpHandlerapplication.Current.Handler属性设置自定义。这是一个例子

于 2013-10-03T15:06:00.487 回答