Compartir vía


Crear una restricción de ruta personalizada (C#)

por Stephen Walther

Stephen Walther muestra cómo puede crear una restricción de ruta personalizada. Implementamos una restricción personalizada sencilla que impide que una ruta coincida cuando se realiza una solicitud del explorador desde un equipo remoto.

El objetivo de este tutorial es demostrar cómo puede crear una restricción de ruta personalizada. Una restricción de ruta personalizada permite evitar que una ruta coincida a menos que se coincida con alguna condición personalizada.

En este tutorial, creamos una restricción de ruta localhost. La restricción de ruta localhost solo coincide con las solicitudes realizadas desde el equipo local. Las solicitudes remotas desde internet no coinciden.

Para implementar una restricción de ruta personalizada, implemente la interfaz IRouteConstraint. Se trata de una interfaz extremadamente sencilla que describe un único método:

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

Este método devuelve un valor booleano. Si devuelve false, la ruta asociada a la restricción no coincidirá con la solicitud del explorador.

La restricción Localhost se encuentra en la lista 1.

Lista 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;
        }
    }
}

La restricción de la lista 1 aprovecha la propiedad IsLocal expuesta por la clase HttpRequest. Esta propiedad devuelve true cuando la dirección IP de la solicitud es 127.0.0.1 o cuando la dirección IP de la solicitud es la misma que la dirección IP del servidor.

Use una restricción personalizada dentro de una ruta definida en el archivo Global.asax. El archivo Global.asax de la lista 2 usa la restricción Localhost para evitar que cualquier usuario solicite una página de administrador a menos que realice la solicitud desde el servidor local. Por ejemplo, se producirá un error en una solicitud de /Admin/DeleteAll cuando se realice desde un servidor remoto.

Lista 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);
        }
    }
}

La restricción Localhost se usa en la definición de la ruta de administración. Esta ruta no coincidirá con una solicitud de explorador remoto. Sin embargo, tenga en cuenta que otras rutas definidas en Global.asax podrían coincidir con la misma solicitud. Es importante comprender que una restricción impide que una ruta determinada coincida con una solicitud y no todas las rutas definidas en el archivo Global.asax.

Observe que la ruta predeterminada se ha comentado desde el archivo Global.asax en la lista 2. Si incluye la ruta predeterminada, la ruta predeterminada coincidiría con las solicitudes del controlador de administración. En ese caso, los usuarios remotos todavía podrían invocar acciones del controlador de administración aunque sus solicitudes no coincidan con la ruta de administración.