1

我想在什么类中获取来自服务器的请求中的什么事件Http Module

我的意思是敌人示例:当用户单击Page1我想获取的按钮时:Button1_Click in Page1类或当用户更改该页面中的下拉列表选择索引时,我想获取DropdownList1_SelectedIndexChange in Page1类。

谢谢

4

5 回答 5

2

页面事件与页面相关联。模块是生命周期事件。您不会从事件模块中看到任何点击类型事件,从另一篇文章中收听此类事件

BeginRequest
AuthenticateRequest
AuthorizeRequest
ResolveRequestCache
AcquireRequestState
PreRequestHandlerExecute
PostRequestHandlerExecute
ReleaseRequestState
UpdateRequestCache
EndRequest

HTTPModule 事件执行顺序?

于 2013-01-01T06:53:08.703 回答
1

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

你能提供更多细节吗?

于 2013-01-07T00:51:26.093 回答
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,那么您将需要在您的模块中处理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
}

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

希望这可以帮助。

于 2013-01-07T19:10:19.393 回答
1

关于您的问题,我注意到以下评论:

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

因为事件是在类中注册的,在Module/Handler阶段是不可用的,所以你问的都做不到。

但是,总有一些选择,我可以看到您要实现的目标:-) 我的解决方案是通过调用方法(myEventHooks.HookAll(this); )简单地注册所有事件并在钩子实现中检查安全性(并且在检查失败时抛出异常或删除所有已注册的事件 - 填写您认为合适的空白)。

请注意,当您更改 Children / 树时,您需要更新事件挂钩以绑定到它们的所有方法。进行绑定的最简单方法是在基本页面中覆盖 RaisePostBackEvent,然后挂钩所有内容。

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

我的解决方案有 2 个部分:(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();
于 2013-01-10T08:57:08.450 回答
1

您的问题非常广泛,以下 MSDN 库文档参考可能会帮助您理解此过程:

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

  1. 验证请求,它检查浏览器发送的信息并确定它是否包含潜在的恶意标记。
  2. 如果在 Web.config 文件的 UrlMappingsSection 部分中配置了任何 URL,则执行 URL 映射。
  3. 引发BeginRequest事件。
  4. 引发AuthenticateRequest事件。
  5. 引发PostAuthenticateRequest事件。
  6. 引发AuthorizeRequest事件。
  7. 引发PostAuthorizeRequest事件。
  8. 引发ResolveRequestCache事件。
  9. 引发PostResolveRequestCache事件。
  10. [IIS 5.0/6.0]根据请求资源的文件扩展名(映射在应用程序的配置文件中),选择一个实现IHttpHandler的类来处理请求。如果请求是针对从 Page 类派生的对象(页面)并且需要编译页面,则 ASP.NET 在创建页面实例之前编译页面。[IIS 7.0]引发MapRequestHandler事件。根据所请求资源的文件扩展名选择适当的处理程序。处理程序可以是本机代码模块,例如 IIS 7.0 StaticFileModule,也可以是托管代码模块,例如 PageHandlerFactory 类(处理 .aspx 文件)。
  11. 引发PostMapRequestHandler事件。
  12. 引发AcquireRequestState事件。
  13. 引发PostAcquireRequestState事件。
  14. 引发PreRequestHandlerExecute事件。
  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 模块概述

于 2013-01-01T07:20:28.427 回答