2013-10-03 113 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