<%@ Application CodeBehind="Global.aspx.cs" Inherits="MyApp1.Global" Language="C#" %>Globalクラスは以下のようなかたちになりHttpApplicationを継承しているのがわかります。
public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { //アプリケーションの初期化時に1回だけ実行されるメソッド } protected void Application_Error(object sender, EventArgs e) { //アプリケーションで補足されなかったエラーが実行されるメソッド } protected void Application_BeginRequest(object sender, EventArgs e) { //リクエストの開始時に実行されるメソッド } protected void Application_AuthenticateRequest(object sender, EventArgs e) { //認証時に実行されるメソッド } }HttpApplicationオブジェクト(Globalオブジェクト)は毎リクエストごとに生成されてそれぞれのメソッドが実行されます。 全てのメソッドが毎リクエストごとに呼ばれるわけではなく中には特定の条件のときだけ呼び出されるメソッドもあります。 以下のメソッドがそのメソッドです。
BeginRequest | リクエストを受信して最初に発生するイベントです。 |
AuthenticateRequest |
ASP.NETがユーザーの認証処理の準備が完了したときに発生します。 このイベントを使用してユーザーの認証処理をカスタマイズすることが可能です。 |
AuthorizeRequest |
権限の承認処理の準備が完了したときに発生します。 このイベントを使用してユーザーへの権限の承認処理をカスタマイズすることが可能です。 |
ResolveRequestCache |
リクエストに対してキャッシュからレスポンスを生成するのかレスポンスを1から生成するのかを決定します。 このイベントを使用してキャッシュの振る舞いをカスタマイズすることが可能です。 |
AcquireRequestState |
セッション変数の準備処理を行います。 このイベントを使用して独自のセッション変数の機構を組み込むことが可能です。 |
PreRequestHandlerExecute |
各ハンドラーへ処理を委譲する直前に発生します。 ハンドラーの実行直前に何かしらの処理をしたい場合はこのイベントを使用します。 |
PostRequestHandlerExecute |
各ハンドラーへ処理の実行直後に発生します。 ハンドラーの実行直後に何かしらの処理をしたい場合はこのイベントを使用します。 |
ReleaserequestState | セッション変数などの値を更新・保存するためのイベントです。 |
UpdateRequestCache | リクエストキャッシュの更新処理を行うためのイベントです。 |
EndRequest | クライアントのブラウザへデータを送信する直前に発生します。 |
public class MyHttpModule : IHttpModule { public void Init(HttpApplication context) { var cx = context; cx.BeginRequest += this.ValidateDosAttack; cx.PreRequestHandlerExecute += this.RegisterHandlerStartTime; cx.PostRequestHandlerExecute += this.RegisterHandlerEndTime; } void ValidateDosAttack(object sender, EventArgs a) { //DOS攻撃かどうかを検証 } void RegisterHandlerStartTime(object sender, EventArgs a) { //ハンドラーの実行開始時刻を記録 } void RegisterHandlerEndTime(object sender, EventArgs a) { //ハンドラーの実行終了時刻を記録 } }HttpModuleのイベントの登録は上記で示したデリゲートで登録する方法と特定の規約に従ってメソッド名をつける方法があります。 "Onイベント名"というかたちでメソッドを作成するとそのメソッドは対応するイベントのときに自動で呼ばれます。
public class MyHttpModule : IHttpModule { void OnBeginRequest(object sender, EventArgs a) { //DOS攻撃かどうかを検証 } void OnPreRequestHandlerExecute(object sender, EventArgs a) { //ハンドラーの実行開始時刻を記録 } void OnPostRequestHandlerExecute(object sender, EventArgs a) { //ハンドラーの実行終了時刻を記録 } }作成したHttpModuleをweb.configで登録します。
<configuration> <system.web> <httpModules> <add name="MyHttpModule" type="MyHttpModule" /> </httpModules> </system.web> </configuration>これで任意のイベントのタイミングで独自の処理を組み込むことが可能です。一般的に組み込む処理としては
<httpModules> <add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/> <add name="Session" type="System.Web.SessionState.SessionStateModule"/> <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule"/> <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/> <add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule"/> <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/> <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule"/> <add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/> </httpModules>HttpModuleを使用することで全てのリクエストに対して特定のタイミングで処理を実行することが可能です。
<httpHandlers> <add verb="*" path="*.vjsproj" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.java" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.jsl" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="trace.axd" type="System.Web.Handlers.TraceHandler"/> <add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory"/> <add verb="*" path="*.ashx" type="System.Web.UI.SimpleHandlerFactory"/> <add verb="*" path="*.asmx" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="false"/> <add verb="*" path="*.rem" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/> <add verb="*" path="*.soap" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/> <add verb="*" path="*.asax" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.ascx" type="System.Web.HttpForbiddenHandler"/> <add verb="GET,HEAD" path="*.dll.config" type="System.Web.StaticFileHandler"/> <add verb="GET,HEAD" path="*.exe.config" type="System.Web.StaticFileHandler"/> <add verb="*" path="*.config" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.cs" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.csproj" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.vb" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.vbproj" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.webinfo" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.asp" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.licx" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.resx" type="System.Web.HttpForbiddenHandler"/> <add verb="*" path="*.resources" type="System.Web.HttpForbiddenHandler"/> <add verb="GET,HEAD" path="*" type="System.Web.StaticFileHandler"/> <add verb="*" path="*" type="System.Web.HttpMethodNotAllowedHandler"/> </httpHandlers>例えばMyPage1.aspxへのリクエストが来た場合、System.Web.UI.PageHandlerFactoryによってハンドラーが生成され 処理を行います。画像などの静的ファイルの場合はSystem.Web.StaticFileHandlerが処理を実行します。 閲覧させたくないファイルに対してはSystem.Web.HttpForbiddenHandlerが設定されておりこれによって.cs、.csprojなどの リクエストが来たとしても無視するようになっています。
<%@ WebHandler Language="C#" Class="ImageHandler" %> using System; using System.Web; using System.Configuration; using System.Data.SqlClient; namespace MyApp1 { public class ImageHandler : IHttpHandler { public void ProcessRequest (HttpContext context) { string imageid = context.Request.QueryString["ImageID"]; using (SqlConnection cn = new SqlConnection("...")) { connection.Open(); SqlCommand command = new SqlCommand("select ImageData from ImageTable where ImageID=" + imageid, cn); SqlDataReader dr = command.ExecuteReader(); dr.Read(); context.Response.BinaryWrite((Byte[])dr[0]); connection.Close(); } context.Response.End(); } public bool IsReusable { get { return false; } } } }独自のハンドラを作成するにはIHttpHandlerインターフェースを実装してProcessRequestメソッドとIsReusableプロパティを 作成するかたちになります。 すると以下のようなURLでアクセスすると画像のダウンロードができるようになります。
http://www.myapp1.com/ImageHandler.ashx?ImageID=001上記のURLだと拡張子が.ashxなのでSystem.Web.UI.SimpleHandlerFactoryクラスがどのハンドラを生成するのか判断することになります。 リクエストのURLを元にMyApp1.ImageHandlerを使用すると判断し、ImageHandlerオブジェクトを生成して処理を行う形になります。