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

Методы контроллера пива

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

Любые идеи?


person Jay    schedule 26.09.2013    source источник


Ответы (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 }
);
person asymptoticFault    schedule 26.09.2013
comment
Я только что попробовал это - это все еще не маршрутизация. Не удается получить ресурс: Запрошенный URL: /Beers/110 Метод действия Id не срабатывает. Я попытался создать новый метод действия под названием BeerById и использовать его для избегайте путаницы с методом Id.. он просто не подбирает правило маршрутизации.. точки останова Global.asax.cs также не попадают - person Jay; 26.09.2013
comment
@Jay Вам следует запрашивать /Beer/110, а не Beers. Ваш маршрут точно соответствует Beer. - person asymptoticFault; 26.09.2013
comment
@Jay Кажется, у меня все работает. Также имя маршрута должно быть уникальным, у вас не может быть двух названий Beer. Я изменил идентификатор на Id, а имя на Name. - person asymptoticFault; 26.09.2013