How can I create a route constraint of type System.Guid?

后端 未结 6 1870
太阳男子
太阳男子 2020-12-01 07:46

Can anyone point me in the right direction on how to map a route which requires two guids?

ie. http://blah.com/somecontroller/someaction/{firstGuid}/{secondGuid}

相关标签:
6条回答
  • 2020-12-01 07:58

    Create a RouteConstraint like the following:

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

    Next when adding the route :

    routes.MapRoute("doubleGuid", "{controller}/{action}/{guid1}/{guid2}", new { controller = "YourController", action = "YourAction" }, new { guid1 = new GuidConstraint(), guid2 = new GuidConstraint() });
    
    0 讨论(0)
  • 2020-12-01 08:00

    If you use kazimanzurrashid's code, make sure to include Nikos D's comment. I ended up with this:

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 08:05

    +1 @kazimanzurrashid. Seems spot on.

    I'll give an alternative for those who haven't got C#4.0, of which Guid.TryParse is part of. There's another alternative with Regex but 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;
            }
        }
    
    0 讨论(0)
  • 2020-12-01 08:10

    Definitely be wary of the code given by @kazimanzurrashid. It was a good start, but it definitely has a bug or too. I was passing a real Guid into the route values (instead of a string of a Guid), and I couldn't get anything to match my route. It took me forever to realize that the GuidConstraint was constraining against a real Guid, if that makes any sense. :)

    Here's what I ended up with, which accepts any data type (not just string), is a bit faster (I think), and contains less if block nesting.

    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 讨论(0)
  • 2020-12-01 08:13

    For MVC 5 there is already implemented the GuidRouteConstraint Class:
    https://msdn.microsoft.com/en-us/library/system.web.mvc.routing.constraints.guidrouteconstraint(v=vs.118).aspx

    Full list of available MVC constraints:
    https://msdn.microsoft.com/en-us/library/system.web.mvc.routing.constraints(v=vs.118).

    0 讨论(0)
  • 2020-12-01 08:19

    I found that assuming the type is a Guid causes issue when using things like @Html.RouteLink(...) and in Routing tests where the URL is supplied as a string. The code below caters for these situations. Using the above code samples caused issues in my views and/or tests, this below works fine.

     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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题