我想创建一个模块化的ASP.NET应用程序。有点像,我有一个主要的应用程序,只是某种模块加载器。它只有一个" Default.aspx"页。并且,基于加载的模块,此页面将创建一个菜单并链接到模块中的页面。
我希望模块是ASP.NET项目打包到dll中。所以,我想把这个dll放到" Modules"我的主应用程序的文件夹,它将识别模块,并使用反射加载模块,检查它们以查找页面,并从中构建菜单。
到目前为止我做了什么:
在我的解决方案中,我有一个" DummyModule"项目。这个项目只有3页。没什么特别的。
我还有一个名为" MainApp"的项目。这是"重要的事情"。
在这个项目中,我有一个" ModuleLoader"类。当" LoadModules"方法被调用,它搜索" dll" "模块"中的文件我的申请文件夹。并且,使用反射,加载这些模块。这些模块的前端,仍然使用反射,它搜索所有" Page"类型,并将名称存储到列表中。
在" Page_Load" " Default.aspx"的方法页面,它调用de" ModuleLoader" class,获取每个模块的所有模块名称和所有页面名称,并从中构建菜单。我创建了一个超链接模式,其中包含加载正确页面所需的所有信息。那就是:" / 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实例。
但是当我打电话给" ProcessRequest" IHTTPHandler接口的方法,它不加载页面。
可以这样做吗?有什么想法吗?
编辑:
我已经尝试过@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" %>
所以,我不知道我做错了什么,或者这不是我正在寻找的解决方案。所以,我尝试了其他选择。
我正确标记了&#34; Build Action&#34; &#34; .aspx&#34;文件为&#34;嵌入式资源&#34;,因此可以作为虚拟路径访问。但我仍然遇到上述错误。
答案 0 :(得分:1)
这看起来像是你想写一个VirtualPathProvider
的情况。该类允许您控制逻辑,该逻辑为编译系统提供组件。
当ASP.NET编译页面来处理请求时,默认情况下它只使用ASPX文件和代码隐藏。如果您编写自定义VirtualPathProvider
,则可以告诉它不这样做。因此,每当ASP.NET需要编译特定路径的页面来处理请求时,您的提供者就可以从程序集中提取它。
这是一篇有用的文章:http://support.microsoft.com/kb/910441
答案 1 :(得分:0)
您应该处理模块中的PostMapRequestHandler
事件,并将自定义IHttpHandler
设置为application.Current.Handler
属性。这是一个example。