如何在Http模块中获得什么事件引发

本文关键字:什么 事件 Http 模块 | 更新日期: 2023-09-27 17:50:30

我想获得Http Module中哪个类中的事件导致服务器请求。

我的意思是敌人的例子:当用户点击一个按钮在Page1我想得到:Button1_Click in Page1类或当用户改变下拉列表选择索引在该页我想得到DropdownList1_SelectedIndexChange in Page1类。

thanks

如何在Http模块中获得什么事件引发

页面事件与页面相关联。模块是生命周期事件。你不会从事件模块中看到任何点击类型的事件,就像从另一个帖子

BeginRequest
AuthenticateRequest
AuthorizeRequest
ResolveRequestCache
AcquireRequestState
PreRequestHandlerExecute
PostRequestHandlerExecute
ReleaseRequestState
UpdateRequestCache
EndRequest

HTTPModule事件执行顺序?

你的问题非常广泛,下面的MSDN库文档参考可能会帮助你理解这个过程:

  • ASP。. NET应用程序生命周期概述IIS 5.0和6.0
  • ASP。. NET应用程序生命周期概述IIS 7.0

下面是ASP的事件和请求管道。NET 4.0:

  1. 验证请求,检查浏览器发送的信息,并确定它是否包含潜在的恶意标记。
  2. 执行URL映射,如果在Web的urlappingssection部分配置了URL。配置文件。
  3. 引发BeginRequest事件。
  4. 引发AuthenticateRequest事件。
  5. 引发PostAuthenticateRequest事件
  6. 引发AuthorizeRequest事件。
  7. 引发PostAuthorizeRequest事件。
  8. 引发ResolveRequestCache事件。
  9. 引发PostResolveRequestCache事件。
  10. [IIS 5.0/6.0]根据请求资源的文件扩展名(映射到应用程序的配置文件中),选择实现IHttpHandler的类来处理请求。如果请求是针对从page类派生的对象(页面),并且需要编译该页面,则ASP. js. NET在创建页的实例之前编译该页。[IIS 7.0]引发MapRequestHandler事件。根据所请求资源的文件扩展名选择适当的处理程序。处理程序可以是本机代码模块,如IIS 7.0 StaticFileModule,也可以是托管代码模块,如PageHandlerFactory类(处理.aspx文件)。
  11. 引发PostMapRequestHandler事件。
  12. 引发AcquireRequestState事件。
  13. 引发PostAcquireRequestState事件。
  14. 引发 preequesthandlerexecute 事件。
  15. 调用相应IHttpHandler类的ProcessRequest方法(或异步版本IHttpAsyncHandler.BeginProcessRequest)。例如,如果请求是针对页面的,则当前页面实例将处理该请求。
  16. 引发PostRequestHandlerExecute事件
  17. 引发ReleaseRequestState事件
  18. 引发PostReleaseRequestState事件。
  19. 如果定义了Filter属性,执行响应过滤。
  20. 引发UpdateRequestCache事件
  21. 引发PostUpdateRequestCache事件
  22. [IIS 7.0] 提高 LogRequest
  23. [IIS 7.0]引发PostLogRequest事件。
  24. 引发EndRequest事件。
  25. 引发PreSendRequestHeaders事件。
  26. 引发PreSendRequestContent事件。

注意: MapRequestHandler, LogRequest, and PostLogRequest events仅在IIS 7.0和。net Framework 3.0或更高版本中以集成模式运行时才支持。

参考遵循:HTTP处理程序和HTTP模块概述

您正在寻找的事件是特定于asp.net页面模型的。Http模块处于较低级别(基于传输),不会用于捕获页面事件。

你能提供更多的细节吗?

我建议,如果你开始一个网站从页面继承一个类,并使你所有的页面都继承这个类。

public abstract class LoggingPage : System.Web.UI.Page
{
    protected override void RaisePostBackEvent(
        IPostBackEventHandler sourceControl, string eventArgument)
    {
        //doing something with the information.
        EventLog.WriteEntry("Page event for " + sourceControl.UniqueID + " at " + this.Request.Url);
        //then call the base implementation
        base.RaisePostBackEvent(sourceControl, eventArgument);
    }
}

如果你需要获得事件的信息,因为异常,你永远不会得到RaisePostBackEvent,那么你需要处理PreRequestHandlerExecuteHttpApplication在你的模块,并在请求中获得2个字段

public class LoggingModule : System.Web.IHttpModule
{
    private HttpApplication _app;
    public void Dispose() 
    {
        this._app.PreRequestHandlerExecute -= new EventHandler(this.PreRequestExecution);
    }
    public void Init(HttpApplication application)
    {
        this._app = application;
        this._app.PreRequestHandlerExecute += new EventHandler(this.PreRequestExecution);
    }
    private void PreRequestExecution(object sender, EventArgs e)
    {
        var request = this._app.Context.Request;
        var target = request.Form["__EVENTTARGET"];
        var arg = request.Form["__EVENTARGUMENT"];
        //this gives you enough information about events
        //you need to check if they are null before using them (target and arg)
        //through the same request you can get extra info including URL
    }
}

更新:
如果您关心的是安全性,并且由于您在系统中实现了角色,我建议使用System.Security.Permissions.PrincipalPermissionAttribute来修饰您的事件处理程序,如下所示:

protected void Page_Load()
{
    myButton.Click += new EventHandler(this.myButton_Click);
}
[PrincipalPermission(SecurityAction.Demand, Role = "Administrator")]
private void myButton_Click(object sender, EventArgs e)
{
    //your code to handle the event
}

您可以根据需要多次添加属性。

关于你的问题,我注意到了这句话:

我想开发一个安全系统,为事件添加一些属性(对于可以访问该事件的角色),并使用会话和该属性检查授权。我想要获取事件名称和属于它的属性并检查授权

因为事件是在类中注册的,在模块/处理程序阶段不可用,所以你的请求无法完成。

然而,总是有选项,我可以看到你想要实现的:-)我的解决方案是通过调用一个方法(myEventHooks.HookAll(this);)来简单地注册所有事件,并在钩子实现中检查安全性(当检查失败时抛出异常或删除所有注册的事件——无论你认为合适,都要填补空白)。

注意,当你改变Children/树时,你需要更新事件钩子来绑定到它们的所有方法。最简单的绑定方法是在基页中重写RaisePostBackEvent,然后把所有内容都挂起来。

这个解决方案可以通过几种不同的方式进行改进;最明显的是使处理更通用,并且缺少0参数处理程序。为了通关,我尽量简化了。这应该可以让你开始。

我的解决方案有两部分:(1)一个泛型钩子类和(2)窗体中的实现。目前的解决方案是懒惰的,例如,我把事件处理程序放在队列的末尾,而不是前面。你应该能够通过使用GetInvocationList或类似的东西来修复这个问题。

泛型钩子类基本上是钩子事件并在事件被调用时触发:

public class EventHooks
{
    private class EventHooksEquality : IEqualityComparer<Tuple<string, object>>
    {
        public bool Equals(Tuple<string, object> x, Tuple<string, object> y)
        {
            return x.Item1.Equals(y.Item1) && object.ReferenceEquals(x.Item2, y.Item2);
        }
        public int GetHashCode(Tuple<string, object> obj)
        {
            return obj.Item1.GetHashCode();
        }
    }
    public void CheckSecurity(string eventName, object container) 
    {
        // Add your security code that checks attributes and the likes here
    }
    private abstract class BaseHookHandler
    {
        protected BaseHookHandler(object container, string eventName, EventHooks hooks)
        {
            this.hooks = hooks;
            this.container = container;
            this.eventName = eventName;
        }
        protected string eventName;
        protected object container;
        protected EventHooks hooks;
    }
    private class HookHandler<T1> : BaseHookHandler
    {
        public HookHandler(object container, string eventName, EventHooks hooks)
            : base(container, eventName, hooks)
        {
        }
        public void Handle(T1 t1)
        {
            hooks.CheckSecurity(eventName, container);
        }
    }
    private class HookHandler<T1, T2> : BaseHookHandler
    {
        public HookHandler(object container, string eventName, EventHooks hooks)
            : base(container, eventName, hooks)
        {
        }
        public void Handle(T1 t1, T2 t2)
        {
            hooks.CheckSecurity(eventName, container);
        }
    }
    // add more handlers here...
    public void HookAll(object obj)
    {
        foreach (var eventHandler in obj.GetType().GetEvents()) 
        {
            Hook(obj, eventHandler.Name);
        }
    }
    public void Hook(object obj, string eventHandler)
    {
        if (obj == null)
        {
            throw new Exception("You have to initialize the object before hooking events.");
        }
        // Create a handler with the right signature
        var field = obj.GetType().GetEvent(eventHandler);
        var delegateInvoke = field.EventHandlerType.GetMethod("Invoke");
        Type[] parameterTypes = delegateInvoke.GetParameters().Select((a) => (a.ParameterType)).ToArray();
        // Select the handler with the correct number of parameters
        var genericHandler = Type.GetType(GetType().FullName + "+HookHandler`" + parameterTypes.Length);
        var handlerType = genericHandler.MakeGenericType(parameterTypes);
        var handlerObject = Activator.CreateInstance(handlerType, obj, eventHandler, this);
        var handler = handlerType.GetMethod("Handle");
        // Create a delegate
        var del = Delegate.CreateDelegate(field.EventHandlerType, handlerObject, handler);
        // Add the handler to the event itself
        field.AddEventHandler(obj, del);
    }
}

在基类中的使用方法如下(示例):

    protected override void RaisePostBackEvent(
        IPostBackEventHandler sourceControl, string eventArgument)
    {
        // Hook everything in Page.Controls
        Stack<Control> st = new Stack<Control>();
        st.Push(Page);
        while (st.Count > 0)
        {
            var control = st.Pop();
            eventHooks.HookAll(control);
            foreach (Control child in control.Controls)
            {
                st.Push(child);
            }
        }
        // Raise events
        base.RaisePostBackEvent(sourceControl, eventArgument);
    }
    private EventHooks hooks = new EventHooks();