ジェネリック ハンドラーにURLルーティングをして、RouteDataを取得するコードを紹介します。
概要
ASP.NETではURLルーティングを利用して、URLを書き換えて別のWebフォームへのアクセスに指定することができます。Webフォームにルーティングすする場合は大きな問題はありませんが、ジェネリックハンドラーにルーティングした場合、ジェネリックハンドラー内ではRouteDataが取得できないため、対策が必要です。
対応方法
URLルーティングのルーティング先をURLの文字列で書き換えた先のURLにすることが多いですが、
IRouteHandler
を継承したクラスを直接指定します。クラスをルーティング先に指定するとルーティングによりURLの書き換えと、ルーティング先に指定したオブジェクトの
GetHttpHandler
が実行されます。
GetHttpHandler
メソッドに引数として
RequestContext
が渡されます。この、
RequestContext
オブジェクト内にルーティング情報である
RouteData
が格納されており、ルーティング情報にアクセスできます。
GetHttpHandler
ハンドラ内でジェネリックハンドラーのオブジェクトを作成することで、ジェネリックハンドラーの処理を呼び出すことができます。ジェネリックハンドラへのRouteDataの情報の受け渡しは、ジェネリックハンドラ側に、
RequestContext
型のメンバ変数を用意し、ジェネリックハンドラ作成時に、メンバ変数に、
RequestContext
を代入することで情報を渡します。
プログラム例
コード
下記のコード、ファイルを準備します。
プロジェクトの新しい項目の追加で、"グローバル アプリケーション クラス"を選択し、Global.asaxファイルを追加します。
Global.asaxにルーティングのコードを記述します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Web.Routing;
namespace AspNetRoutingGenericHandler
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Route myRoute = new Route("action/{*productid}", null);
myRoute.RouteHandler = new MyHttpHandler();
RouteTable.Routes.Add("", myRoute);
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
ルーティングにより呼び出されるクラスです。このクラスは、
IRouteHandler
の派生クラスである必要があります。プロジェクトの新しい項目の追加で"ASP.NET ハンドラー"を選択して追加し、派生元クラスの
IHttpHandler
を
IRouteHandler
に書き換えるか、新しい項目の追加で"クラス"を追加して下記のコードを記述します。
using System;
using System.Web;
using System.Web.Routing;
namespace AspNetRoutingGenericHandler
{
public class MyHttpHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new MyHandler() { RequestContextRouting = requestContext };
}
}
}
ジェネリックハンドラを作成します。プロジェクトの新しい項目の追加で"ジェネリック ハンドラー"を選択して追加し下記のコードを記述します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;
namespace AspNetRoutingGenericHandler
{
/// <summary>
/// MyHandler の概要の説明です
/// </summary>
public class MyHandler : IHttpHandler
{
public RequestContext RequestContextRouting;
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
if (RequestContextRouting.RouteData != null) {
string pid = RequestContextRouting.RouteData.Values["productid"].ToString();
context.Response.Write(pid);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
解説
Global.asax
ASP.NETのURLルーティングの実装コードを記述します。多くの場合、URLルーティングではルーティング先のURLを指定しますが、今回はURLではなく
IRouteHandler
を実装したクラス
MyHttpHander
を指定します。
MyHttpHandler.cs
URLルーティングにより呼び出されるクラスです。このクラスでは処理をせず、
GetHttpHandler
メソッドの戻り値で処理を実行するジェネリックハンドラのインスタンスを返します。
MyHandler.ashx.cs
処理のロジックが実装されたジェネリックハンドラです。今回の例では、ルーティング元のURLの末尾部分の階層名を取得し画面に表示しています。
実行結果
プロジェクトを実行しWebブラウザが表示されますので、下記のURLにアクセスします。
http://localhost:57587/action/PenguinCookie
ページが表示されます。ページにURLのaction以下の"productid"の値が表示されます。MyHandler.ashxでの処理によりRouteDataの取得ができていることが確認できます。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2024-01-06
作成日: 2018-01-31