我想跟踪我的ASP.NET Web Forms
应用程序中的一些用户活动。例如,我将使用该方法,protected void btnSearch_Click(object sender, EventArgs args)
因为它代表了我的更多业务需求和编程问题。
只是为了使其更加清楚。我要实现的是,当btnSearch_Click
执行时要对INSERT
包含一些基本信息的数据库表执行操作,例如执行了哪些确切动作,何时执行,谁执行了该动作以及搜索词是什么。我将要跟踪很多动作,因此表的结构仍然有待确定,但这是总体思路。
我的第一个想法是使用一些静态类,例如:
public static class UserHistory
{
public static void Log(string methodName, string user, string message)
{
//execute SQL INSERT
}
}
然后在需要保持历史记录的事件处理程序中添加:
UserHistory.Log("btnSearch_Click", "SomeUser", "The user searched for cats");
实际上,这对于我来说似乎已经可以接受,并不是我不特别喜欢这种方法,而是首先-这是非常常见的任务,这类任务通常已经具有一些模式,可以帮助您最好地实现逻辑可能的方式和第二,我不是非常有经验,我看到这里有机会通过做一些事情来扩大我的知识,这在特定情况下可能不是有益的,但反正还是要知道的。
因此,这导致了我的Observer
模式。老实说,与代表一起工作对我来说总是很麻烦,但是我也在努力学习,我知道证明自己为解决某些问题做出了自己的努力是无足轻重的,所以我要解释一下我应该做的事情使用这种模式,但会得出一些我可以参考的完整答案。
我发现的最简单的例子是Jon Skeet
他实现两个类的答案:
class Observable
{
public event EventHandler SomethingHappened;
public void DoSomething()
{
EventHandler handler = SomethingHappened;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
和
class Observer
{
public void HandleEvent(object sender, EventArgs args)
{
Console.WriteLine("Something happened to " + sender);
}
}
展示其工作原理的具体示例是:
static void Main(string[] args)
{
Observable observable = new Observable();
Observer observer = new Observer();
observable.SomethingHappened += observer.HandleEvent;
observable.DoSomething();
}
也许它包含足够的信息来实现Web表单的这种模式,但是我无法在cotntext的此处检测到不同的角色Web Forms
。
我期望有一个地方可以注册我要跟踪的所有事件,例如:
protected void Page_Load(object sender, EventArgs e)
{
observable.SomethingHappened += btnSearch_Click;
observable.SomethingHappened += btnLogin_Click;
}
但是,如果我尝试这样做,实际上什么也没做。我什至不进去:
public void DoSomething()
{
EventHandler handler = SomethingHappened;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
这是合乎逻辑的,但是如果我必须从要记录某些内容的每个方法中显式调用此方法,那么与使用普通的旧静态方法有何区别?另外,我想传递一个参数(字符串消息),但我也不知道该怎么做。因此,我对如何使用委托人/事件了解得很少,但是如果有人帮助我实现这一点,我将不胜感激。例如可以在btnSearch_Click
事件处理程序中使用我想将搜索字符串作为参数传递的地方。
在这种情况下,您不必自己实现Observer模式。ASP.NET管道已经以Application对象上的回调的形式为您实现了它;在这种情况下,PostAuthorizeRequest回调应该可以很好地处理您的需求。
首先,在WebForms管道上有一个快速的侧边栏:在WebForms中处理UI交互的方式是通过称为PostBacks的抽象进行的。在您看来,您似乎正在处理从.aspx / .ascx控件引发的事件,而实际上发生的是将请求(包含特殊命名字段的POST)发送到Web服务器。将创建页面的新实例来处理该请求,WebForms基础结构将检测到它是PostBack,并调用事件处理程序。(有关更多信息,请参见MSDN文档)
这对您意味着什么?好吧,如果您在Global.asax(或Global.asax.cs后面的代码)中为应用程序挂接PostAuthorizeRequest回调,则可以在识别用户并为他们授予执行请求的权限后检查请求。特别是,您将需要注意三件事:首先,这是什么类型的请求?如果不是POST,则不是PostBack,您可以在此处停止自定义处理。其次,请求的实际路径-这是用户正在与之交互的WebForms页面;如果不是您对审核事件感兴趣的页面,请在此处停止。最后,PostBack的目标是什么?可以通过检查HttpContext.Request.Form [“ __ EVENTTARGET”]的值来确定。如果这是控件的名称,
实际上这是什么样的?假设您有一个元组的查找表,该表将页面+控件名称映射到消息。在我的示例中,我将使用IDictionary变量auditMap,为简单起见,我将使用页面路径和控件名称的串联(例如:“ MyPage.aspx :: btnSearch”)执行查找有关审核消息:
void Application_PostAuthorizeRequest(object sender, EventArgs e)
{
if (HttpContext.Current.Request.HttpMethod != "POST") return;
String key = String.Concat(HttpContext.Current.Request.Path, "::", HttpContext.Current.Request.Form["__EVENTTARGET"]);
String message;
if (!auditMap.TryGetValue(key, out message) return;
auditService.LogEvent(message);
// Can also pass HttpContext.Current.User.Identity.Name into a format string, etc.
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句