2013-10-03 114 views
2

我想创建一个模块化的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”,因此它可以作为虚拟路径访问。但我仍然有上面的错误。

+1

你或许应该写一个'VirtualPathProvider'代替。 – SLaks

回答

0

您应该处理模块中的PostMapRequestHandler事件,并将自定义IHttpHandler设置为application.Current.Handler属性。这是一个example

+0

我试过了,并用自己的页面覆盖了请求处理程序,作为处理程序,但我得到的只是一个空白页面。有任何想法吗? – Bruno

1

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

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

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

+0

在搜索anwser时,我发现并尝试了一个类似的解决方案,实现了我自己的VirtualPathProvider和VirtualFile。 它几乎奏效。 虚拟路径句柄并加载正确的页面,但是当页面加载时,我得到以下错误: 解析器错误消息:无法加载类型'DummyModule.Pages.DummyPage3'。 源错误: 第1行:<%@页面语言= “C#” AutoEventWireup = “真” 的CodeBehind = “DummyPage3.aspx.cs” 继承= “DummyModule.Pages.DummyPage3” %> 所以,我不不知道我做错了什么,或者这不是我正在寻找的解决方案。所以,我尝试了其他选择。 – Bruno