2010-03-11 2 views

Répondre

48

Créer une RouteConstraint comme ce qui suit:

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

suivant lors de l'ajout de la route:

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

ajoutez juste un "if (values ​​[parameterName] is Guid) return true;" pour capturer les paramètres fortement typés, comme par exemple des tests et pour le routage sortant;) –

+3

Les performances du code peuvent être améliorées en changeant "values.ContainsKey" en "values.TryGetValue" et en supprimant les valeurs [parameterName] call. – ShadowChaser

+0

Mais 'if (values.ContainsKey (parameterName))' check est vraiment inutile, à cause d'une fonctionnalité d'indexeur RouteValueDictionary - il renvoie null si la clé n'existe pas dans la collection [RouteValueDictionary.Item Property sur MSDN] (http://msdn.microsoft.com/en-us/library/system.web.routing.routevaluedictionary.item%28v=vs.110%29.aspx). –

2

+1 @kazimanzurrashid. Semble tache sur.

Je vais donner une alternative pour ceux qui n'ont pas C# 4.0, dont Guid.TryParse fait partie. Il y a une autre alternative avec Regex mais 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 contrainte de route pour la "alternative avec Regex" ressemble à ceci: 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

Downvote due à try {} catch {}. Attraper toutes les exceptions est généralement considéré comme une mauvaise pratique de programmation, et l'exception est un coup de performance. Utilisez Guid.TryParse pour éviter l'exception à la place. – ShadowChaser

+0

@ShadowChaser c'est exactement ce que j'ai dit dans ma réponse, TryParse est recommandé mais seulement disponible avec C# 4.0 – dove

10

Si vous utilisez le code de kazimanzurrashid, assurez-vous d'inclure le commentaire de Nikos D'. Je me suis retrouvé avec ceci:

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

Méfiez-vous du code donné par @kazimanzurrashid. C'était un bon début, mais il a certainement un bug ou aussi. Je passais un vrai Guid dans les valeurs de route (au lieu d'une chaîne de Guid), et je ne pouvais rien obtenir pour correspondre à mon itinéraire. Il m'a fallu une éternité pour réaliser que le GuidConstraint était contraint par rapport à un vrai Guid, si cela a du sens. :)

Voici ce que j'ai fini avec, qui accepte tout type de données (pas seulement de la chaîne), est un peu plus rapide (je pense), et contient moins si le bloc imbrique.

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

Je trouve que en supposant que le type est un Guid fait problème lors de l'utilisation des choses comme @ Html.RouteLink (...) et dans les tests de routage où l'URL est fournie en tant que chaîne. Le code ci-dessous répond à ces situations. En utilisant les exemples de code ci-dessus causé des problèmes dans mes vues et/ou des tests, ce qui suit fonctionne très 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

Ceci est également disponible pour l'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 –

Questions connexes