のサーバーからのリクエストを引き起こすクラスのイベントを取得したい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モジュールは下位レベル(トランスポートベース)であり、ページイベントのキャプチャには使用されません。
詳細を教えてください。
あなたの質問は非常に広範囲であり、次の 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 以降を使用して実行されている場合にのみサポートされます。
Web サイトでページからクラスを継承し、すべてのページがこのクラスから継承されるようにすることをお勧めします。
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
}
必要に応じて、属性を複数回追加できます。
お役に立てれば。
あなたの質問に関して、私は次の発言に気付きました:
イベントにいくつかの属性を追加し(このイベントにアクセスできるロール用)、セッションとこの属性を使用して承認をチェックするセキュリティ システムを開発したい。イベント名を取得し、それに属する属性を取得して承認をチェックしたい
イベントはクラスに登録されているため、モジュール/ハンドラー フェーズでは使用できません。要求したことは実行できません。
ただし、常にオプションがあり、あなたが達成しようとしていることを見ることができます:-)私の解決策は、メソッド( myEventHooks.HookAll(this); )を呼び出してすべてのイベントを登録し、フック実装でセキュリティをチェックすることです(チェックが失敗した場合は、例外をスローするか、登録されているすべてのイベントを削除します。必要に応じてギャップを埋めます)。
Children / ツリーを変更する場合は、イベント フックを更新してすべてのメソッドにもバインドする必要があることに注意してください。バインディングを行う最も簡単な方法は、ベース ページで RaisePostBackEvent をオーバーライドしてから、すべてをフックすることです。
このソリューションは、いくつかの異なる方法で改善できます。最も明らかに、処理もより一般的になり、0 パラメーター ハンドラーがなくなります。クリアランスのためにできるだけシンプルにしました。これで始められるはずです。
私のソリューションには、(1) 一般的なフック クラスと (2) フォーム内の実装の 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();