Hypen в MVC 3 маршрута
Вот мой желаемый формат URL: / product-24-hid-35wh4-cx-dsgtx
Как я могу сопоставить этот URL с моим методом действия:
public ActionResult Product(int id)
Вот мой код маршрутизации:
routes.MapRoute(
"ProductDetail",
"product-{id}-{name}",
new { controller = "product", action = "detail", name = UrlParameter.Optional },
new string[] { "SphereLight.Controllers" }
);
Тем не менее, это не работает; Я использовал маршрутный отладчик Фила Хака для проверки этого маршрута, и ниже приведен результат:
Key Value
name dsgtx
id 24-hid-35wh4-cx
controller product
action detail
Только id = 24 является правильным.
Одним словом, мне нужен маршрут, чтобы соответствовать:
/product-24
/product-24-
/product-24-hid-35wh4-cx-dsgtx
1 ответ
Попробуйте добавить ограничения в свой MapRoute:
routes.MapRoute(
"ProductDetail",
"product-{id}-{name}",
new { controller = "product", action = "detail", name = UrlParameter.Optional },
new { id = @"\d+" }, // <-- change it for @"[^-]+", if it can be non-digit
new string[] { "SphereLight.Controllers" }
);
ОБНОВИТЬ:
Наконец то понял.
Основная проблема заключается в том, что вы не можете использовать параметры, содержащие один и тот же разделитель. Например, приведенный выше пример будет работать с /product-24-nm
, но не с product-24-nm-smth
,
Итак, давайте попробуем это решение:
Я сделал это на маршрутизации по умолчанию, вы можете сделать это по-своему
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new MyRouteHandler()
).RouteHandler = new MyRouteHandler();
Реализация MyRouteHandler
:
public class MyRouteHandler : MvcRouteHandler
{
private static readonly Regex ProductPattern = new Regex(@"product\-(\d+)\-?(.*)");
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
var match = ProductPattern.Match(requestContext.RouteData.Values["controller"].ToString());
if (match.Length > 0)
{
requestContext.RouteData.Values["controller"] = "Home";
requestContext.RouteData.Values["action"] = "Detail";
requestContext.RouteData.Values["id"] = match.Groups[1].Value;
requestContext.RouteData.Values["name"] = match.Groups[2].Value;
}
return base.GetHttpHandler(requestContext);
}
}
Итак, основная идея - проверить, соответствуют ли значения нашему шаблону. product-id-name
в обработчике, и не пытается сделать это в MapRoute
, Надеюсь это поможет.