カスタム ルート制約を作成する (C#)

投稿者: Stephen Walther

Stephen Walther が、カスタム ルート制約を作成する方法を示しています。 リモート コンピューターからブラウザー要求が行われたときにルートの照合を避ける、シンプルなカスタム制約を実装します。

このチュートリアルの目的は、カスタム ルート制約を作成する方法を示すことです。 カスタム ルート制約を使用すると、何らかのカスタム条件が一致しない限り、ルートの照合を避けることができます。

このチュートリアルでは、Localhost ルート制約を作成します。 Localhost ルート制約は、ローカル コンピューターから行われた要求のみを照合します。 インターネット経由からのリモート要求は照合されません。

カスタム ルート制約を実装するために、IRouteConstraint インターフェイスを実装します。 これは、単一のメソッドを記述する非常にシンプルなインターフェイスです。

bool Match(
    HttpContextBase httpContext,
    Route route,
    string parameterName,
    RouteValueDictionary values,
    RouteDirection routeDirection
)

このメソッドは、ブール値を返します。 False を返した場合、制約に関連付けられているルートはブラウザー要求を照合しません。

Localhost 制約はリスト 1 に含まれています。

リスト 1 - LocalhostConstraint.cs

using System.Web;
using System.Web.Routing;
namespace MvcApplication1.Constraints
{
    public class LocalhostConstraint : IRouteConstraint
    {
        public bool Match
            (
                HttpContextBase httpContext, 
                Route route, 
                string parameterName, 
                RouteValueDictionary values, 
                RouteDirection routeDirection
            )
        {
            return httpContext.Request.IsLocal;
        }
    }
}

リスト 1 の制約では、HttpRequest クラスによって公開される IsLocal プロパティを利用します。 このプロパティは、要求の IP アドレスが 127.0.0.1 の場合、または要求の IP がサーバーの IP アドレスと同じ場合に true を返します。

Global.asax ファイルで定義されているルート内でカスタム制約を使用します。 リスト 2 の Global.asax ファイルでは、Localhost 制約を使用して、ローカル サーバーから要求を行わない限り、どのユーザーも管理者ページを要求できないようにします。 たとえば、リモート サーバーから /Admin/DeleteAll を要求すると失敗します。

リスト 1 - Global.asax

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using MvcApplication1.Constraints;
namespace MvcApplication1
{
    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                "Admin",
                "Admin/{action}",
                new {controller="Admin"},
                new {isLocal=new LocalhostConstraint()}
            );
            //routes.MapRoute(
            //    "Default",                                              // Route name
            //    "{controller}/{action}/{id}",                           // URL with parameters
            //    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            //);
        }
        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
        }
    }
}

Localhost 制約は、管理ルートの定義で使用されます。 このルートは、リモート ブラウザー要求では照合されません。 ただし、Global.asax で定義されている他のルートが同じ要求を照合する可能性があることに注意してください。 制約によって防ぐものは、特定のルートが要求を照合することであり、Global.asax ファイルで定義されているすべてのルートではないことに注意することが重要です。

リスト 2 の Global.asax ファイルから既定のルートがコメント アウトされていることに注意してください。 既定のルートを含めると、既定のルートは Admin コントローラーの要求を照合します。 その場合、リモート ユーザーは、要求が Admin ルートを照合しなくても、Admin コントローラーのアクションを呼び出す場合があります。