Как я могу реализовать "естественные" таблицы маршрутизации схемы URL в ASP.NET MVC - PullRequest
8 голосов
/ 16 февраля 2011

Я хотел бы указать свои таблицы маршрутизации так, чтобы они выглядели намного более «естественными»

/Products
/Product/17
/Product/Edit/17
/Product/Create

Близко к конфигурации по умолчанию, но чтобы действие «Индекс» было быотображается в форму, кратную имени контроллера, и действие "Подробности" будет отображаться непосредственно с идентификатором элемента, следующего непосредственно за именем контроллера.

Я знаю, что могу достичь этого явноопределяя специальные сопоставления маршрутизации следующим образом:

routes.MapRoute(
    "ProductsList",
    "Products",
    new { controller = "Product", action = "Index" }
);
routes.MapRoute(
    "ProductDetails",
    "Product/{id}",
    new { controller = "Product", action = "Details" }
);

/*
 * Ditto for all other controllers
 */

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

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

Есть ли способ обобщить это или я связан с физическим трудом в этом случае?

1 Ответ

2 голосов
/ 16 февраля 2011

Вы можете попробовать что-то вроде этого:

routes.MapRoute(
                "ProductsList",
                "{pluralizedControllerName}",
                new { controller = "Home", action = "Index" },
                new { pluralizedControllerName = new PluralConstraint() }
                );

            routes.MapRoute(
                "ProductDetails",
                "{controller}/{id}",
                new { controller = "Home", action = "Details" },
                new { id = @"\d+" }
            );

            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
            );

Обратите внимание на ограничение во втором маршруте, оно гарантирует, что /Product/Create не будет выбрано вторым маршрутом, так что оно будет отображено как третий.

Для тестирования маршрута вы можете использовать routedebugger , а для написания модульного теста для маршрутов попробуйте MvcContrib-TestHelper .Вы можете получить оба с NuGet.

РЕДАКТИРОВАТЬ:

Вы можете использовать этот простой мультипликатор и затем реализовать что-то вроде этого:

public class PluralConstraint : IRouteConstraint
    {
        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            List<string> names = GetControllerNames();//get all controller names from executing assembly
            names.ForEach(n => n.Pluralize(n));
            return names.Contains(values[parameterName]);
        }
    }
...