2012-02-06 114 views
0

我試圖在運行時查找頁面請求的程序集。我使用的代碼爲Get current System.Web.UI.Page from HttpContext?,適用於大多數呼叫,但存在問題。從當前上下文中查找頁面或頁面組合

如果在我的aspx.cs中,我實例化一個類變量,在我的類的頂部HttpContext.Current.CurrentHandler爲空。


我有一個名爲Business.dll與函數來獲取頁類型按照上述SO問題一個DLL。

在我的網頁,在Default.asp的我FrontEnd.dll有以下電話:

public partial class FrontEnd: Page 
{ 
    private readonly Type _t = Business.GetPageType(); 

上面的代碼返回HttpContext.Current.CurrentHandler爲空和返回HttpContext.Current.ApplicationInstance作爲HttpApplication的類型,以及因此System.Web作爲程序集。

如果我寫的卻是這樣的:

public partial class FrontEnd: Page 
{ 
    readonly Type _t; 

    protected override void OnInit(EventArgs e) 
    { 
     _t = Business.GetPageType();  

它工作得很好,我得到CurrentHandler和頁面的引用。我當然可以重構所有地方並將變量初始化移動到OnInit,但這需要在應用程序中進行約定,並且需要更高程度的維護。

使用Assembly.GetEntryAssembly()返回null爲例,Assembly.GetExecutingAssembly()返回Business.dll,所以我也不能使用它們。

是否有可能通過另一種方式來查找類型/ dll,可能使用請求Url來查找它來源的類型/ dll?

[更新]
到目前爲止,我有這個代碼,因爲我所有的DLL都與已知的鑰匙(不包括檢查簽名密鑰的額外的方法)簽署:

StackTrace stackTrace = new StackTrace(); 
StackFrame[] stackFrames = stackTrace.GetFrames(); 
Assembly firstAssembly = null; 
foreach (StackFrame stackFrame in stackFrames) 
{ 
    var method = stackFrame.GetMethod(); 
    Type t = method.DeclaringType; 
    if (t != null && t.Assembly.Is(SignedBy.Me)) 
    { 
     firstAssembly = t.Assembly; 
    } 
} 
if(firstPzlAssembly != null) 
{ 
    return firstPzlAssembly; 
} 

雖然它的工作原理,它似乎是錯誤的,如果經常打電話會有潛在的性能影響。

回答

2

當你做這種方式:

private readonly Type _t = Business.GetPageType(); 

它實際上是構造內編譯成一個字段初始化。 這意味着對象(您的頁面)尚未構建。它還不存在,它是「正在誕生」。在這個階段,你只是在構造函數內的

在構建對象(頁面)之前,ASP.NET基礎結構無法將其分配給HttpContext.Current.CurrentHandler靜態屬性。那麼,因爲處理程序(你的頁面)還不存在,id正在構建。

所以你不能做你想做的。

你可以做的是建立一個PageBase類,重寫OnInit方法並添加以下代碼有:

public abstract class PageBase 
{ 
    protected Type PageType { get; private set; } 

    protected override void OnInit(EventArgs e) 
    { 
     PageType = Business.GetPageType(); 
    } 
} 

現在只得到從這個基類頁面:

public partial class FrontEnd: PageBase { .... } 

(或者在ASPX文件中直接指定PageBase作爲基類,不管你做什麼。

+0

這是有道理的。猜猜我可能必須選擇重新編寫代碼並使用約定,您不能在類中自行初始化變量,但必須在OnInit或類似過程中執行。謝謝。 – 2012-02-06 13:46:57

0

一種選擇是定義一個基本頁面,並根據需要設置OnInit函數,然後確保所有其他頁面都從中繼承。

例如:

public class CustomBasePage: Page 
{ 
    readonly Type _t; 

    protected override void OnInit(EventArgs e) 
    { 
     _t = Business.GetPageType(); 
    } 
} 

然後改變所有的網頁都從這個而不是正常的Page類繼承:

public partial class FrontEnd: CustomBasePage 

這意味着你只需要定義一次你的邏輯,並把一其他應用程序頁面的開銷最小。 如果由於其他原因,任何頁面需要覆蓋OnInit,則只需要包含對base.OnInit();的調用,這不是太繁重。

你需要確保你的Business.GetPageType();返回你所期望的。我不清楚它到底在做什麼,它是否會返回FrontEndCustomBasePage類,(也不會爲您的應用程序邏輯接受哪些類)。

+0

如果business.dll有關什麼基類正在使用(我有一個)的新功能,我們與其他頁面基類相同的共享Business.dll。問題是它們都在同一個實例(SharePoint)中運行,所以我必須找出哪一個執行了調用。 – 2012-02-06 13:45:09

相關問題