我想创建一个模块化的 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”文件的“构建操作”标记为“嵌入式资源”,因此它可以作为虚拟路径访问。但我仍然得到上面的错误。