我想创建一个模块化的ASP.NET应用程序。就像,我有一个主要的应用程序,只是某种模块加载器。它只有一个“Default.aspx”页面。并且,基于加载的模块,此页面将创建一个菜单并链接到模块中找到的页面。从DLL动态加载ASP.NET页面
我想要的模块打包成DLL ASP.NET项目。所以,我想把这个DLL放到我的主应用程序的“Modules”文件夹中,它将识别模块,并使用反射来加载模块,检查它们以找到页面,并从中创建一个菜单。
什么我迄今所做的:
在我的解决方案,我有一个“DummyModule”项目。这个项目只有3页。没什么特别的。
而我有另一个名为“MainApp”的项目。这是“大不了”。
在这个项目中,我有一个“ModuleLoader组件”类。当调用“LoadModules”方法时,它会在我的应用程序的“Modules”文件夹中搜索“dll”文件。并且,使用反射,加载这些模块。这些模块仍然使用反射,它搜索所有“页面”类型,并将名称存储到列表中。
在“Default.aspx”页面的“Page_Load”方法中,它调用de“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”的方法,找到指定程序正确的“页面”类型,创建一个实例,并返回该页面实例。
但是当我打电话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”文件的“Build Action”标记为“Embedded Resource”,因此它可以作为虚拟路径访问。但我仍然有上面的错误。
你或许应该写一个'VirtualPathProvider'代替。 – SLaks