2012-02-06 119 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

相关问题