2008-09-04 1 views
3

Я ищу некоторые примеры или образцы маршрутизации для следующего рода сценарий:Категории контроллеров в маршрутизации MVC? (имена Дублированных контроллеров в отдельных Namespaces)

Общий пример делать вещи: {контроллер}/{действие}/{ид }

Таким образом, в случае выполнения поиска продукта для магазина вы бы:

public class ProductsController: Controller 
{ 
    public ActionResult Search(string id) // id being the search string 
    { ... } 
} 

Скажем, у вас было несколько магазинов, чтобы сделать это, и вы хотели, чтобы последовательно, есть ли способ, чтобы затем имеют: {category}/{controller}/{action}/{id}

Чтобы вы могли найти конкретный поиск для определенного магазина, но используете другой метод поиска для другого магазина?

(Если требуется название магазина, чтобы быть более высоким приоритетом, чем сама функция в URL)

Или это дошедшее до:

public class ProductsController: Controller 
{ 
    public ActionResult Search(int category, string id) // id being the search string 
    { 
     if(category == 1) return Category1Search(); 
     if(category == 2) return Category2Search(); 
     ... 
    } 
} 

Это не может быть отличным примером, но в основном идея состоит в том, чтобы использовать одно и то же имя контроллера и, следовательно, иметь простой URL-адрес в нескольких разных сценариях, или вы застряли с требованием уникальных имен контроллеров и не можете помещать их в несколько разных пространств имен/каталогов?

Изменить, чтобы добавить:

Другая причина я хочу это потому, что я мог бы хотеть URL, который имеет категории, и что некоторые контроллеры будут работать только в определенных категориях.

IE:

/это/поиск/пункты/поиск + термин < - работает

/что/поиск/пункты/поиск + термин < - не будет работать - потому что контроллер поиска не допускается.

+0

Означает ли понятие «районы» в выпуске 1.0? – hometoast 2009-06-01 01:10:30

ответ

1

Лучший способ сделать это без каких-либо компромиссов - это реализовать собственный ControllerFactory путем наследования IControllerFactory. Метод CreateController, который будет реализовывать дескрипторы, создающие экземпляр контроллера для обработки запроса с помощью RouteHandler и ControllerActionInvoker. Соглашением является использование имени контроллера при его создании, поэтому вам придется переопределить эту функциональность. Это будет ваша логика для создания контроллера на основе маршрута, так как у вас будет несколько контроллеров с тем же именем, но в разных папках. Затем вам нужно будет зарегистрировать фабрику настраиваемых контроллеров при запуске приложения, как и ваши маршруты.

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

Чтобы получить представление о коде, есть несколько вопросов, на которые я ответил на SO, которые относятся к этому вопросу, но это в какой-то степени отличается, потому что имена контроллеров будут одинаковыми. Я включил ссылки для справки.

Другой маршрут, но может потребоваться некоторые компромиссы будут использовать атрибут новые AcceptVerbs. Проверьте это question для более подробной информации. Я еще не играл с этой новой функциональностью, но это может быть другой маршрут.

4

Я действительно нашел его даже не путем поиска, а путем сканирования через форумы ASP.NET в this question.

С помощью этого вы можете иметь контроллеры одного и того же названия, под любой части пространства имен, так долго, как вы имеете право, какие маршруты принадлежат какие пространства имен (вы можете иметь несколько имен за маршрутами, если вам нужно быть!)

Но отсюда вы можете поместить в каталог под своим контроллером, поэтому, если ваш контроллер был «MyWebShop.Controllers», вы поместили бы каталог «Shop1», а пространство имен было бы «MyWebShop.Controllers.Shop1»

Тогда это работает:

public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

     var shop1namespace = new RouteValueDictionary(); 
     shop1namespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers.Shop1" 
     })); 

     routes.Add("Shop1", new Route("Shop1/{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new 
      { 
       action = "Index", 
       id = (string)null 
      }), 
      DataTokens = shop1namespace 
     }); 

     var shop2namespace = new RouteValueDictionary(); 
     shop2namespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers.Shop2" 
     })); 

     routes.Add("Shop2", new Route("Shop2/{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new 
      { 
       action = "Index", 
       id = (string)null 
      }), 
      DataTokens = shop2namespace 
     }); 

     var defaultnamespace = new RouteValueDictionary(); 
     defaultnamespace.Add("namespaces", new HashSet<string>(new string[] 
     { 
      "MyWebShop.Controllers" 
     })); 

     routes.Add("Default", new Route("{controller}/{action}/{id}", new MvcRouteHandler()) 
     { 
      Defaults = new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }), 
      DataTokens = defaultnamespace    
     }); 
    } 

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

Смежные вопросы