2010-03-11 7 views

Respuesta

48

Crear una RouteConstraint como la siguiente:

public class GuidConstraint : IRouteConstraint { 

public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
{ 
    if (values.ContainsKey(parameterName)) 
    { 
     string stringValue = values[parameterName] as string; 

     if (!string.IsNullOrEmpty(stringValue)) 
     { 
      Guid guidValue; 

      return Guid.TryParse(stringValue, out guidValue) && (guidValue != Guid.Empty); 
     } 
    } 

    return false; 
}} 

siguiente al añadir la ruta:

routes.MapRoute("doubleGuid", "{controller}/{action}/{guid1}/{guid2}", new { controller = "YourController", action = "YourAction" }, new { guid1 = new GuidConstraint(), guid2 = new GuidConstraint() }); 
+8

simplemente agregue un "if (values ​​[parameterName] es Guid) return true;" para capturar los parámetros fuertemente tipados, como por ejemplo de las pruebas y para el enrutamiento de salida;) –

+3

El rendimiento del código se puede mejorar cambiando "values.ContainsKey" a "values.TryGetValue" y eliminando la llamada a los valores [parameterName]. – ShadowChaser

+0

Pero la comprobación 'if (values.ContainsKey (parameterName))' es realmente innecesaria, debido a una función del indexador RouteValueDictionary; devuelve null si la clave no existe en la colección [RouteValueDictionary.Item Property en MSDN] (http://msdn.microsoft.com/en-us/library/system.web.routing.routevaluedictionary.item%28v=vs.110%29.aspx). –

2

+1 @kazimanzurrashid. Parece perfecto.

Daré una alternativa para aquellos que no tienen C# 4.0, de los cuales Guid.TryParse es parte de. Hay otra alternativa con expresiones regulares, pero probably not worth the bother.

public class GuidConstraint : IRouteConstraint 
    { 

     public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
     { 
      if (values.ContainsKey(parameterName)) 
      { 
       string stringValue = values[parameterName] as string; 

       if (!string.IsNullOrEmpty(stringValue)) 
       { 
        //replace with Guid.TryParse when available. 
        try 
        { 
         Guid guid = new Guid(stringValue); 
         return true; 
        } 
        catch 
        { 
         return false; 
        } 


       } 
      } 

      return false; 
     } 
    } 
+2

La restricción de ruta para la "alternativa con Regex" tiene el siguiente aspecto: new {guid = @ "^ (\ {) {0,1} [0-9a-fA-F] {8} \ - [0-9a -fA-F] {4} \ - [0-9a-fA-F] {4} \ - [0-9a-fA-F] {4} \ - [0-9a-fA-F] {12} (\}) {0,1} $ "} –

+0

Downvoting debido a try {} catch {}. La captura de todas las excepciones generalmente se considera como una mala práctica de programación, y la excepción es un golpe de rendimiento. Use Guid.TryParse para evitar la excepción en su lugar. – ShadowChaser

+0

@ ShadowChaser eso es exactamente lo que dije en mi respuesta, TryParse se recomienda pero solo está disponible con C# 4.0 – dove

10

Si utiliza código de kazimanzurrashid, asegúrese de incluir Nikos D's comentario. Terminé con esto:

public class NonEmptyGuidRouteConstraint : IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, Route route, 
     string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     if (values.ContainsKey(parameterName)) 
     { 
      var guid = values[parameterName] as Guid?; 
      if (!guid.HasValue) 
      { 
       var stringValue = values[parameterName] as string; 
       if (!string.IsNullOrWhiteSpace(stringValue)) 
       { 
        Guid parsedGuid; 
        Guid.TryParse(stringValue, out parsedGuid); 
        guid = parsedGuid; 
       } 
      } 
      return (guid.HasValue && guid.Value != Guid.Empty); 
     } 
     return false; 
    } 
} 
6

Indudablemente tenga cuidado con el código dado por @kazimanzurrashid. Fue un buen comienzo, pero definitivamente también tiene un error. Estaba pasando un Guid real en los valores de la ruta (en lugar de una cadena de Guid), y no pude obtener nada para que coincida con mi ruta. Me llevó mucho tiempo darme cuenta de que GuidConstraint era restrictivo contra Guid, si tiene sentido. :)

Esto es lo que terminé con, que acepta cualquier tipo de datos (no solo de cadena), es un poco más rápido (creo) y contiene menos si el bloque anida.

public class GuidConstraint : IRouteConstraint 
{ 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     object value; 
     if (!values.TryGetValue(parameterName, out value)) return false; 
     if (value is Guid) return true; 

     var stringValue = Convert.ToString(value); 
     if (string.IsNullOrWhiteSpace(stringValue)) return false; 

     Guid guidValue; 
     if (!Guid.TryParse(stringValue, out guidValue)) return false; 
     if (guidValue == Guid.Empty) return false; 

     return true; 
    } 
} 
0

me encontré con que suponiendo que el tipo es un GUID causa problema cuando se utiliza cosas como @ Html.RouteLink (...) y en las pruebas de enrutamiento donde la URL se suministra como una cadena. El código a continuación cubre estas situaciones. El uso de los ejemplos de código anteriores causó problemas en mis vistas y/o pruebas, esto a continuación funciona bien.

public class GuidConstraint : IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     var value = values[parameterName]; 
     if (value == null) return false; 
     var stringValue = value.ToString(); 

     if (string.IsNullOrEmpty(stringValue)) return false; 
     Guid guidValue; 
     return Guid.TryParse(stringValue, out guidValue) && (guidValue != Guid.Empty); 
    } 
} 
16
+0

Esto también está disponible para la API web: https://msdn.microsoft.com/en-us/library/system.web.http.routing.constraints.guidrouteconstraint(v=vs.118).aspx, https: // msdn.microsoft.com/en-us/library/system.web.http.routing.constraints(v=vs.118).aspx –

Cuestiones relacionadas