asp.Net Маршрутизация MVC 3 на основе количества сегментов

#asp.net-mvc-3 #asp.net-mvc-routing

#asp.net-mvc-3 #asp.net-mvc-routing

Вопрос:

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

 routes.MapRoute(
            "Image",                                        
            "Image/{action}/{width}/{height}/{file}",       
            new { controller = "Image", action = "Thumbnail", width = 250, height = 250 }
        );

routes.MapRoute(
           "GetCampaignsByCampaignType",
           "Endorsement/GetCampaignsByCampaignType/{campaignType}",
           new { controller = "Endorsement", action = "GetCampaignsByCampaignType" }
        );

routes.MapRoute(
            "Help",
            "Help",
            new { controller = "Help", action = "Contact" } 
        );

routes.MapRoute(
            "Campaigns",
            "Campaigns",
            new { controller = "Endorsement", action = "Campaigns" } 
        );

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

routes.MapRoute(
            "Campaign",
            "{campaignUrlName}",
            new { controller = "Endorsement", action = "GetCampaign" }
        );
 

Вопрос связан с нижними 2 маршрутами. У меня есть кампании типа /Summer, / Winter , / Some-other-name, где у меня их сотни, и я бы не хотел их жестко кодировать. У меня также есть другие маршруты, которые я хочу использовать, например /Campaign/ Account , /Help/Me/Please (где есть более одного сегмента / 1 / 2 или /1/2/3 )

Каков правильный порядок или определение, позволяющие мне / 1 перейти к последнему маршруту, определенному выше, и / 1 / 2 или /1/2/3 перейдите к {controller}/{action}/{id} по умолчанию

В настоящее время в обоих сценариях используется маршрут по умолчанию {controller}/{action}/{id}, включающий /1. Если я поменяю их местами, то /1 будет работать, но /1/ 2 или /1/2/3 не переходит к маршрутизации по умолчанию.

Любая помощь приветствуется.

Ответ №1:

Найдено решение с помощью регулярных выражений:

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

        routes.MapRoute(
            "Campaign",
            "{campaignUrlName}",
            new { controller = "Endorsement", action = "GetCampaign" },
            new { campaignUrlName = @"^([a-zA-Z])[a-zA-Z_-]*[w_-]*[S]$|^([a-zA-Z])[0-9_-]*[S]$|^[a-zA-Z]*[S]$" }
        );
 

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

Ответ №2:

Ваш маршрут по умолчанию всегда будет переопределять маршрут вашей кампании, потому что существуют значения по умолчанию для контроллера и метода. Таким образом, /Winter будет интерпретироваться как «WinterController» (который не существует) с индексом по умолчанию (который также не существует), поэтому вы получите 404.

Вам нужно будет определить конкретные маршруты для /Winter и /Summer и т. Д. И поместить их перед значением по умолчанию.

Комментарии:

1. В том-то и дело, что у меня их сотни, если не тысячи. Я не могу их жестко запрограммировать. Должен быть лучший способ. Нужно будет выяснить, что это такое. Тем не менее, спасибо за ваш ответ. Просто еще не готов потерпеть поражение.

2. Ну, всегда есть другие способы. Вы могли бы написать свой собственный обработчик маршрута, который ищет кампании в базе данных, и если он их не находит, то вызывает маршрут по умолчанию.

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

4. @gsogoly — Пользовательское ограничение вам не поможет, потому что вы все равно не сможете отличить кампанию от запроса по умолчанию. Вы всегда получите либо одно, либо другое. Единственный способ получить и то, и другое — это провести какой-то поиск, чтобы узнать, какие кампании являются действительными.