Подтвердить что ты не робот

Как создать ограничение маршрута типа System.Guid?

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

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

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

4b9b3361

Ответ 1

Создайте RouteConstraint, как показано ниже:

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

Ответ 3

Если вы используете код kazimanzurrashid, обязательно включите комментарий Nikos D. Я закончил с этим:

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

Ответ 4

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

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

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

Ответ 5

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

Я дам альтернативу тем, у кого нет С# 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;
        }
    }

Ответ 6

Я обнаружил, что при условии, что тип является причиной 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);
    }
}