Как я могу создать ограничение маршрута типа System.Guid? - PullRequest
39 голосов
/ 11 марта 2010

Может ли кто-нибудь указать мне правильное направление, как составить карту маршрута, для которого требуется два гида?

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

, где firstGuid и secondGuid не являются обязательными и должны иметь тип system.Guid?

Ответы [ 6 ]

48 голосов
/ 12 марта 2010

Создайте ограничение маршрута, как показано ниже:

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

Далее при добавлении маршрута:

routes.MapRoute("doubleGuid", "{controller}/{action}/{guid1}/{guid2}", new { controller = "YourController", action = "YourAction" }, new { guid1 = new GuidConstraint(), guid2 = new GuidConstraint() });
19 голосов
/ 20 апреля 2015

Для MVC 5 уже реализован класс GuidRouteConstraint :
https://msdn.microsoft.com/en-us/library/system.web.mvc.routing.constraints.guidrouteconstraint(v=vs.118).aspx

Полный список доступных ограничений MVC:
https://msdn.microsoft.com/en-us/library/system.web.mvc.routing.constraints(v=vs.118).

10 голосов
/ 16 октября 2011

Если вы используете код Казиманзуррашида, обязательно добавьте комментарий Никоса Д. Я закончил с этим:

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 голосов
/ 25 января 2013

Определенно будьте осторожны с кодом, заданным @kazimanzurrashid. Это было хорошее начало, но оно определенно имеет ошибку или слишком. Я передавал настоящий Guid в значения маршрута (вместо строки Guid), и я не мог получить ничего, что соответствовало бы моему маршруту. Мне потребовалось целую вечность, чтобы понять, что GuidConstraint ограничивает реальный Guid , если это имеет смысл. :)

Вот то, что я закончил, который принимает любой тип данных (не только строку), немного быстрее (я думаю) и содержит меньше , если блок вложенность.

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;
    }
}
2 голосов
/ 12 марта 2010

+ 1 @kazimanzurrashid. Кажется, пятно на.

Я дам альтернативу тем, у кого нет C # 4.0, частью которого является Guid.TryParse . Есть еще одна альтернатива с Regex, но , вероятно, не стоит беспокоиться.

 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 голосов
/ 11 ноября 2014

Я обнаружил, что если предположить, что тип является Guid, возникает проблема при использовании таких вещей, как @ Html.RouteLink (...) и в тестах маршрутизации, где URL-адрес предоставляется в виде строки. Код ниже обслуживает эти ситуации. Использование приведенных выше примеров кода вызвало проблемы в моих представлениях и / или тестах, ниже это прекрасно работает.

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