我想在什么类中获取来自服务器的请求中的什么事件Http Module
。
我的意思是敌人示例:当用户单击Page1
我想获取的按钮时:Button1_Click in Page1
类或当用户更改该页面中的下拉列表选择索引时,我想获取DropdownList1_SelectedIndexChange in Page1
类。
谢谢
我想在什么类中获取来自服务器的请求中的什么事件Http Module
。
我的意思是敌人示例:当用户单击Page1
我想获取的按钮时:Button1_Click in Page1
类或当用户更改该页面中的下拉列表选择索引时,我想获取DropdownList1_SelectedIndexChange in Page1
类。
谢谢
页面事件与页面相关联。模块是生命周期事件。您不会从事件模块中看到任何点击类型事件,从另一篇文章中收听此类事件
BeginRequest
AuthenticateRequest
AuthorizeRequest
ResolveRequestCache
AcquireRequestState
PreRequestHandlerExecute
PostRequestHandlerExecute
ReleaseRequestState
UpdateRequestCache
EndRequest
您要查找的事件特定于 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,那么您将需要在您的模块中处理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
}
您可以多次添加属性以满足您的需求。
希望这可以帮助。
关于您的问题,我注意到以下评论:
我想开发一个安全系统,为事件添加一些属性(对于可以访问此事件的角色)并使用会话和此属性检查授权。我想获取事件名称,然后是属于它的属性并检查授权
因为事件是在类中注册的,在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();
您的问题非常广泛,以下 MSDN 库文档参考可能会帮助您理解此过程:
以下是 ASP.NET 4.0 的事件和请求管道:
- 验证请求,它检查浏览器发送的信息并确定它是否包含潜在的恶意标记。
- 如果在 Web.config 文件的 UrlMappingsSection 部分中配置了任何 URL,则执行 URL 映射。
- 引发BeginRequest事件。
- 引发AuthenticateRequest事件。
- 引发PostAuthenticateRequest事件。
- 引发AuthorizeRequest事件。
- 引发PostAuthorizeRequest事件。
- 引发ResolveRequestCache事件。
- 引发PostResolveRequestCache事件。
- [IIS 5.0/6.0]根据请求资源的文件扩展名(映射在应用程序的配置文件中),选择一个实现IHttpHandler的类来处理请求。如果请求是针对从 Page 类派生的对象(页面)并且需要编译页面,则 ASP.NET 在创建页面实例之前编译页面。[IIS 7.0]引发MapRequestHandler事件。根据所请求资源的文件扩展名选择适当的处理程序。处理程序可以是本机代码模块,例如 IIS 7.0 StaticFileModule,也可以是托管代码模块,例如 PageHandlerFactory 类(处理 .aspx 文件)。
- 引发PostMapRequestHandler事件。
- 引发AcquireRequestState事件。
- 引发PostAcquireRequestState事件。
- 引发PreRequestHandlerExecute事件。
- 为请求调用相应 IHttpHandler 类的 ProcessRequest 方法(或异步版本 IHttpAsyncHandler.BeginProcessRequest)。例如,如果请求是针对某个页面的,则当前页面实例会处理该请求。
- 引发PostRequestHandlerExecute事件。
- 引发ReleaseRequestState事件。
- 引发PostReleaseRequestState事件。
- 如果定义了 Filter 属性,则执行响应过滤。
- 引发UpdateRequestCache事件。
- 引发PostUpdateRequestCache事件。
- [IIS 7.0]引发LogRequest事件。
- [IIS 7.0]引发PostLogRequest事件。
- 引发EndRequest事件。
- 引发PreSendRequestHeaders事件。
- 引发PreSendRequestContent事件。
注意:MapRequestHandler, LogRequest, and PostLogRequest events
仅当应用程序在 IIS 7.0 和 .NET Framework 3.0 或更高版本中以集成模式运行时,才受支持。
要遵循的参考: HTTP 处理程序和 HTTP 模块概述