方法はありますが、いくつかのクラスが必要です。
ASP.NET MVCはルートを登録するときに、ルートハンドラーを定義します。このルートハンドラーは、要求を処理するHTTPハンドラーを返します。カスタムHTTPハンドラーを返すカスタムルートハンドラーを使用する場合は、いくつかのデコレータークラスを使用してHTTPコンテキストを書き換えることができます。
基本クラスから派生し、すべてのメソッドとプロパティを内部インスタンスにラップするaHttpContextProxy
とを作成することから始めます。HttpRequestProxy
私はハードワークを利用できるようにしました。
次に、デコレータを作成します。最初にHTTPコンテキストデコレータを作成します。
using System.Web;
public class HttpContextDecorator : HttpContextProxy
{
public HttpContextDecorator(HttpContextBase innerHttpContext)
: base(innerHttpContext)
{
}
public override HttpRequestBase Request
{
get
{
return new HttpRequestDecorator(base.Request);
}
}
}
HTTPリクエストデコレータ:
using System;
using System.Web;
public class HttpRequestDecorator : HttpRequestProxy
{
public HttpRequestDecorator(HttpRequestBase innerHttpRequest)
: base(innerHttpRequest)
{
}
public override bool IsSecureConnection
{
get
{
return string.Equals(Headers["X-Forwarded-Proto"], "https", StringComparison.OrdinalIgnoreCase);
}
}
public override Uri Url
{
get
{
var url = base.Url;
var urlBuilder = new UriBuilder(url);
if (IsSecureConnection)
{
urlBuilder.Port = 443;
urlBuilder.Scheme = "https";
}
else
{
urlBuilder.Port = 80;
}
return urlBuilder.Uri;
}
}
public override string UserHostAddress
{
get
{
const string forwardedForHeader = "HTTP_X_FORWARDED_FOR";
var forwardedFor = ServerVariables[forwardedForHeader];
if (forwardedFor != null)
{
return forwardedFor;
}
return base.UserHostAddress;
}
}
}
前述のように、MVCクラス(ここではHTTPハンドラー)もオーバーライドする必要があります。
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
public class CustomMvcHandler : MvcHandler
{
public CustomMvcHandler(RequestContext requestContext)
: base(requestContext)
{
requestContext.HttpContext = new HttpContextDecorator(requestContext.HttpContext);
}
protected override IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
{
httpContext = new HttpContextDecorator(httpContext);
return base.BeginProcessRequest(httpContext, callback, state);
}
protected override void ProcessRequest(HttpContextBase httpContext)
{
httpContext = new HttpContextDecorator(httpContext);
base.ProcessRequest(httpContext);
}
}
次に、ルートハンドラー:
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
public class CustomMvcRouteHandler : MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new CustomMvcHandler(requestContext);
}
}
最後に、登録されているすべてのルートに関連付けられているハンドラーを置き換える必要があります(または最初から適切にマップします)。
var routes = RouteTable.Routes.OfType<Route>().Where(x => x.RouteHandler is MvcRouteHandler);
foreach (var route in routes)
{
route.RouteHandler = new CustomMvcRouteHandler();
}