如何在Http模块中获取什么事件

时间:2013-01-01 06:14:16

标签: c# asp.net httpmodule

我希望在Http Module中获取来自服务器的哪个类中的哪个事件引起请求。

我的意思是敌人的例子:当用户点击Page1中的按钮时我想得到:Button1_Click in Page1类或当用户更改该页面中的下拉列表选择索引时我想得到{{1 }。class。

感谢

5 个答案:

答案 0 :(得分:2)

页面事件与页面相关联。模块是生命周期事件。您不会在事件模块中看到任何来自其他帖子的任何点击类型事件

BeginRequest
AuthenticateRequest
AuthorizeRequest
ResolveRequestCache
AcquireRequestState
PreRequestHandlerExecute
PostRequestHandlerExecute
ReleaseRequestState
UpdateRequestCache
EndRequest

HTTPModule Event Execution Order?

答案 1 :(得分:1)

您的问题非常广泛,以下MSDN Library文档参考可能有助于您了解此过程:

以下是ASP.NET 4.0的事件和请求管道:

  
      
  1. 验证请求,该请求检查浏览器发送的信息并确定其是否包含潜在的恶意标记。
  2.   
  3. 如果在Web.config文件的UrlMappingsSection部分中配置了任何URL,则执行URL映射。
  4.   
  5. 提升 BeginRequest 事件。
  6.   
  7. 举起 AuthenticateRequest 事件。
  8.   
  9. 提高 PostAuthenticateRequest 事件。
  10.   
  11. 提升 AuthorizeRequest 事件。
  12.   
  13. 提升 PostAuthorizeRequest 事件。
  14.   
  15. 提升 ResolveRequestCache 事件。
  16.   
  17. 提升 PostResolveRequestCache 事件。
  18.   
  19. [IIS 5.0 / 6.0] 根据所请求资源的文件扩展名(映射到应用程序的配置文件中),选择一个实现IHttpHandler的类来处理请求。如果请求是针对从Page类派生的对象(页面)并且需要编译页面,则ASP.NET会在创建页面实例之前编译该页面。 [IIS 7.0] 提升 MapRequestHandler 事件。根据所请求资源的文件扩展名选择适当的处理程序。处理程序可以是本机代码模块,例如IIS 7.0 StaticFileModule,也可以是托管代码模块,例如PageHandlerFactory类(处理.aspx文件)。
  20.   
  21. 提升 PostMapRequestHandler 事件。
  22.   
  23. 提升 AcquireRequestState 事件。
  24.   
  25. 提升 PostAcquireRequestState 事件。
  26.   
  27. 举起 PreRequestHandlerExecute 事件。
  28.   
  29. 为请求调用适当的IHttpHandler类的ProcessRequest方法(或异步版本IHttpAsyncHandler.BeginProcessRequest)。例如,如果请求是针对页面的,则当前页面实例处理该请求。
  30.   
  31. 举起 PostRequestHandlerExecute 事件。
  32.   
  33. 提升 ReleaseRequestState 事件。
  34.   
  35. 提升 PostReleaseRequestState 事件。
  36.   
  37. 如果定义了Filter属性,则执行响应过滤。
  38.   
  39. 提升 UpdateRequestCache 事件。
  40.   
  41. 提升 PostUpdateRequestCache 事件。
  42.   
  43. [IIS 7.0] 提升 LogRequest 事件。
  44.   
  45. [IIS 7.0] 提升 PostLogRequest 事件。
  46.   
  47. 提升 EndRequest 事件。
  48.   
  49. 举起 PreSendRequestHeaders 事件。
  50.   
  51. 提升 PreSendRequestContent 事件。
  52.   

注意:仅当应用程序在IIS 7.0中以集成模式运行且使用.NET Framework 3.0或更高版本时,才支持MapRequestHandler, LogRequest, and PostLogRequest events

关注

引用HTTP Handlers and HTTP Modules Overview

答案 2 :(得分:1)

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

你能提供更多细节吗?

答案 3 :(得分:1)

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

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,则需要在模块中处理PreRequestHandlerExecute HttpApplication并在请求中获取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
}

您可以多次添加属性以满足您的需求。

希望这会有所帮助。

答案 4 :(得分:1)

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

  

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

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

然而,总有选项,我可以看到你想要实现的目标:-)我的解决方案是通过调用方法( 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();