正在从当前上下文中查找页面或页面程序集

本文关键字:查找 程序集 上下文 | 更新日期: 2023-09-27 18:22:31

我正试图在运行时查找页面请求的程序集。我使用了从HttpContext获取当前System.Web.UI.Page的代码?这适用于大多数呼叫,但存在一个问题。

如果在我的aspx.cs中,实例化类顶部的类变量HttpContext.Current.CurrentHandler为null。

示例
我有一个名为Business.dll的DLL,它的功能是根据上面的SO问题获得页面类型。

在我的页面,FrontEnd.dll中的default.asp中,我有以下调用:

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

上面的代码返回HttpContext.Current.CurrentHandler为null,HttpContext.CCurrent.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;
}

虽然它有效,但它似乎是错误的,如果经常调用,可能会对性能产生影响。

正在从当前上下文中查找页面或页面程序集

当你这样做时:

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指定为基类,无论您做什么。

一个选项是定义一个基页,根据需要设置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类(也不清楚应用程序逻辑可以接受其中的哪一个)。