MVC 4: пользовательские маршруты

Я вижу много проблем с маршрутами MVC, и у меня похожая проблема с получением маршрута, соответствующего URL.

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

//default route
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

routes.MapRoute("Beer", "Beer/{beerid}", new { controller = "Beer", action = "Id", beerid = 0});

routes.MapRoute("Beer", "Beer/{beername}", new { controller = "Beer", action = "Name" });

Методы BeerController

public ActionResult Id(int beerid)
public ActionResult Name(string beername)

Если я изменю методы на следующие,

public ActionResult Id(int? id)    
public ActionResult Name(string id)

Маршрутизация по умолчанию работает со следующими URL:

http://localhost/Beer/Id/100
http://localhost/Beer/Name/Coors

Но то, что я собираюсь, это просто

http://localhost/Beer/100
http://localhost/Beer/Coors

Есть идеи?

1 ответ

Решение

Итак, пара вещей здесь.

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

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

    routes.MapRoute(
        name: "Beer",
        url: "Beer/{beerid}",
        defaults: new { controller = "Beer", action = "Id", beerid = 0},
        constraints: new { beerid = @"\d+" }
    );
    

    Ограничение будет гарантировать, что маршрут соответствует только двухсегментным URL-адресам, где второй сегмент состоит из одной или нескольких цифр. Этот маршрут, а также ваш маршрут для названия пива должны быть указаны до маршрута по умолчанию.

ОБНОВИТЬ

Моя конфигурация, кажется, дает желаемые результаты. Весь мой RegisterRoutes Метод заключается в следующем:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
    name: "Id",
    url: "Beer/{beerid}",
    defaults: new { controller = "Beer", action = "Id", beerid = 0 },
    constraints: new { beerid = @"\d+" }
);

routes.MapRoute(
    name: "Name",
    url: "Beer/{beername}",
    defaults: new { controller = "Beer", action = "Name" }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Другие вопросы по тегам