我希望在Http Module
中获取来自服务器的哪个类中的哪个事件引起请求。
我的意思是敌人的例子:当用户点击Page1
中的按钮时我想得到:Button1_Click in Page1
类或当用户更改该页面中的下拉列表选择索引时我想得到{{1 }。class。
感谢
答案 0 :(得分:2)
页面事件与页面相关联。模块是生命周期事件。您不会在事件模块中看到任何来自其他帖子的任何点击类型事件
BeginRequest
AuthenticateRequest
AuthorizeRequest
ResolveRequestCache
AcquireRequestState
PreRequestHandlerExecute
PostRequestHandlerExecute
ReleaseRequestState
UpdateRequestCache
EndRequest
答案 1 :(得分:1)
您的问题非常广泛,以下MSDN Library文档参考可能有助于您了解此过程:
以下是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 事件。
醇>
注意:仅当应用程序在IIS 7.0中以集成模式运行且使用.NET Framework 3.0或更高版本时,才支持MapRequestHandler, LogRequest, and PostLogRequest events
。
答案 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();