ASPNET MVC: как я могу сделать страницу, расположенную в заданной области (в отличие от корневой структуры) по умолчанию? - PullRequest
2 голосов
/ 09 сентября 2010

Как и где я могу настроить свое приложение таким образом, чтобы при его запуске действие (то есть отображаемая страница) находилось не в корневой структуре, а в определенной области по моему выбору?

Допустим, Action = " IndexOfArticles ", Controller = " Articles ", Area = " News ". Я хочу, чтобы этот параметр использовался по умолчанию при запуске приложения.

Я работал с классом NewsAreaRegistration и настраивал вышеуказанную конфигурацию. теперь я подозреваю, что для того, чтобы это работало, мне нужно что-то сделать и с Global.asx.cs, но я не знаю, что делать.

EDIT

Это то, что я имею в виду

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

Приведенный выше код, например, приведет к запуску приложения с действием Index , расположенным в Home controller для выполнения. Это не то, что я хочу. Спасибо за помощь.

Ответы [ 2 ]

3 голосов
/ 10 сентября 2010

Учитывая природу вопросов, которые вы задавали, я хочу порекомендовать ресурс, который, я думаю, вы ДЕЙСТВИТЕЛЬНО полюбите.Книга Стивена Сандерсона "Pro ASP.NET MVC 2 Framework (второе издание)" по адресу.Глава 8, в частности, содержит много подробностей о маршрутизации и областях.Сама книга отличная и продуманная;один из лучших примеров книг по разработке / программированию, которые я когда-либо читал.Он доступен в форме Kindle, и если вы заказываете у apress напрямую, вы можете получить его в виде электронной книги в формате PDF.Конечно, он также доступен в бумажной форме:

Amazon Link

или

Напрямую от Apress

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

Маршрут в примере с Манафом работает «случайно» больше, чем намеренно, поэтому, вероятно, вы не совсем понимаете, что он делает.Существует странность с неоднозначными именами контроллеров в «корневой области» (то есть в папке контроллера, которой нет в области).Поскольку маршрут ведет к корневой области, но он не может найти там контроллер, он будет сканировать все области в поисках совпадения.В этом случае он находит совпадение в вашем пространстве имен новостей и работает.Но это сканирование работает, только если совпадает только один контроллер.Таким образом, если вы создадите другой контроллер в другой области с тем же именем, он потерпит неудачу с исключением типа «найдено несколько типов».

У вас есть два хороших способа сделать эту работу более надежной.Либо, установив приоритет области новостей в маршрутах, либо перенаправив:

Перенаправление:

Вместо того, чтобы направлять корневые запросы к контроллеру в определенной области, вы можете перенаправить Браузер на URL-адресобласть, с которой вы хотите, чтобы они начали.Поэтому они начинаются с "yoursite.com/" и будут перенаправлены на URL "yoursite.com/news/articles".Для этого вы создаете контроллер корневого уровня и используете маршрут по умолчанию.Итак, создайте HomeController в корневой папке контроллеров (а не в области).На этом контроллере создайте метод действия с именем Index.И в этом методе Index перенаправьте их на контроллер, на котором вы действительно хотите, чтобы они запускались.

В global.asax вы можете положиться на довольно стандартный маршрут по умолчанию, подобный следующему:

routes.MapRoute(    
     "Default",  
     "{controller}/{action}/{id}",  
     new { controller = "Home", action = "Index", id = UrlParameters.Optional }  
); 

В вашем действии Index на контроллере Home просто перенаправьте клиент на нужный контроллер вобласть новостей с использованием RedirectToAction и указанием области:

return RedirectToAction("IndexOfArticles", "Articles", new { area = "News" });

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

routes.MapRoute(
    "Default",
    "{controller}/{acion}/{id}",
    new {controller = "Articles", action = "IndexOfArticles", id = UrlParameters.Optional},
    new[] {"YourApplication.News"}
);

Недостатком этого является то, что 4-й параметр (пространства имен) будет применяться ко всем запросам, поэтому он может привести к перенаправлению большего количества данныхваша конкретная новость, чем вы хотели.Может быть, лучше быть более точным во втором параметре, чтобы этот маршрут не перехватывал другие запросы ... возможно, установите второй параметр в пустую строку, чтобы он только перехватывал корневой запрос сайта.

2 голосов
/ 09 сентября 2010

Пользовательские маршруты к вашим районам должны быть зарегистрированы в вашем классе AreaRegistration Не в Global.asx.cs

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

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

Ваши маршруты в методе RegisterArea должны выглядеть примерно так:

        context.MapRoute(
            "News_default",
            "News/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional }
        );

        context.MapRoute(
            "DefaultStart",
            "",
            new { controller = "Articles", action = "IndexOfArticles"}
        );

Обновление : забыл упомянуть, что вам необходимо убедиться, что вы зарегистрировали свои области в методе Application_Start в файле Global.asx.cs.

AreaRegistration.RegisterAllAreas();

Обновление 2: как работает маршрутизация в ASP.NET MVC

Я понимаю ваше беспокойство. Позвольте мне кратко объяснить, как работает маршрутизация.

В ASP.NET MVc есть одна таблица маршрутизации, которая используется для соответствия всем URL-запросам.

Когда вы регистрируете маршрут в Global.asx.cs или в AreaRegistration, эти маршруты добавляются в таблицу маршрутизации в соответствии с порядком, в котором они были зарегистрированы (поэтому заказы важны, и мы должны подтолкнуть наши более конкретные маршруты к сверху, чтобы они могли быть сопоставлены).

Когда речь идет о маршрутах областей (тех, которые зарегистрированы в классе AreaRegistration). Они всегда добавляются в верхнюю часть таблицы маршрутизации до того, как любой из маршрутов, зарегистрированных в файле Global.asx.cs (Маршруты областей являются первыми для сопоставления), которые создаются, поскольку в противном случае вы пропустите совпадение с Областью, называемой Новости для Контроллер с именем News.

Если у вас есть более одной области, маршруты какой области проверяются первыми? Я не уверен на 100%, но экспериментальным путем я обнаружил, что они упорядочены по времени создания, старые области стоят первыми в верхней части таблицы маршрутизации. (это не имеет значения, потому что у вас не будет 2 областей с одинаковым именем)

Примеры:

Предположим, вы создали следующие области. News, Dashboard, Api

и добавил следующий маршрут к вашей NewsAreaRegistration, чтобы соответствовать корневому маршруту, как в примере выше

context.MapRoute(
        "DefaultStart",
        "",
        new { controller = "Articles", action = "IndexOfArticles"}
    );

Ваша таблица маршрутизации будет выглядеть примерно так:

No   Route Name                        URL                               Explanation 
1   News_default         News/{controller}/{action}/{id}          Default For News Area
2   DefaultStart         (empty)                                  Root Route (match root url)
3   Dashboard_default    Dashboard/{controller}/{action}/{id}     Default For Dashboard Area
4   Api_default          Api/{controller}/{action}/{id}           Default For Api Area
5   Default              {controller}/{action}/{id}               Default (No Areas)

Теперь, когда ваше приложение получает запрос. Он будет проходить по маршрутам один за другим и искать совпадения. В нашем случае, когда ваш запрос корневой URL. Второй маршрут будет соответствовать. и поскольку мы устанавливаем значения по умолчанию для controller = "Articles" и action = "IndexOfArticles", запрос будет перенаправлен соответствующим образом.

Надеюсь, это было полезно.

...