Поделиться через


Создание пользовательского ограничения маршрута (C#)

Стивен Уолтер

Стивен Вальтер демонстрирует, как создать пользовательское ограничение маршрута. Мы реализуем простое настраиваемое ограничение, которое предотвращает сопоставление маршрута при выполнении запроса браузера с удаленного компьютера.

Цель этого руководства — продемонстрировать, как создать пользовательское ограничение маршрута. Ограничение настраиваемого маршрута позволяет предотвратить сопоставление маршрута, если не будет сопоставлено какое-то пользовательское условие.

В этом руководстве мы создадим ограничение маршрута 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 использует преимущества свойства IsLocal, предоставляемого классом HttpRequest. Это свойство возвращает значение true, если IP-адрес запроса равен 127.0.0.1 или если IP-адрес запроса совпадает с IP-адресом сервера.

Пользовательское ограничение используется в маршруте, определенном в файле Global.asax. В файле Global.asax в листинге 2 используется ограничение Localhost, чтобы запретить кому-либо запрашивать страницу Администратор, если только он не сделает запрос с локального сервера. Например, запрос /Администратор/DeleteAll завершится ошибкой при выполнении с удаленного сервера.

Листинг 2. 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.

Обратите внимание, что маршрут по умолчанию был закомментирован из файла Global.asax в листинге 2. Если включить маршрут по умолчанию, маршрут по умолчанию будет соответствовать запросам для контроллера Администратор. В этом случае удаленные пользователи по-прежнему могут вызывать действия контроллера Администратор, даже если их запросы не будут соответствовать Администратор маршруту.