Категории контроллеров в MVC Routing? (Дублирующие имена контроллеров в отдельных пространствах имен) - PullRequest
3 голосов
/ 04 сентября 2008

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

Общий пример действий: {controller} / {action} / {id}

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

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:

/ this / search / items / search + term <- works </p>

/ that / search / items / search + term <- не будет работать - потому что контроллер поиска не разрешен. </p>

Ответы [ 2 ]

3 голосов
/ 05 сентября 2008

На самом деле я нашел его даже не путем поиска, а путем сканирования на форумах ASP .NET в этот вопрос .

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

Но отсюда вы можете поместить в каталог под вашим контроллером, поэтому, если ваш контроллер был «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            
        });
    }

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

1 голос
/ 04 сентября 2008

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...