【问题标题】:Dynamically load ASP.NET Page from DLL从 DLL 动态加载 ASP.NET 页面
【发布时间】:2013-10-10 07:32:23
【问题描述】:

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

【问题讨论】:

  • 你应该改写VirtualPathProvider

标签: c# asp.net .net reflection dll


【解决方案1】:

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

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

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

【讨论】:

  • 在搜索 anwser 时,我发现并尝试了类似的解决方案,实现了我自己的 VirtualPathProvider 和 VirtualFile。它几乎奏效了。虚拟路径处理并加载正确的页面,但是在加载页面时,出现以下错误:解析器错误消息:无法加载类型“DummyModule.Pages.DummyPage3”。源错误:第 1 行: 所以,我不知道我是否'做错了什么,或者这不是我正在寻找的解决方案。所以,我尝试了其他选择。
【解决方案2】:

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

【讨论】:

  • 我试过这个,并用我自己的页面覆盖了请求处理程序,作为一个处理程序,但我得到的只是一个空白页。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-07
  • 2022-12-21
  • 1970-01-01
  • 1970-01-01
  • 2011-12-02
  • 2010-09-30
  • 2012-01-31
相关资源
最近更新 更多