ASP.NET MVC Области: Как скрыть имя «Площадь» в URL? - PullRequest
15 голосов
/ 21 апреля 2010

При запуске примера MVC 2 , в котором есть область блога и контроллер блога, URL выглядит следующим образом:

http://localhost:50526/Blog/Blog/ShowRecent в формате:

RootUrl / AreaName / ControllerName / ActionName

Только что обнаружив Области MVC, кажется, что это отличный способ организовать код, то есть создать Области для каждого раздела, который в моем случае имеет свой контроллер. Это означает, что каждый AreaName = ControllerName. Результатом этого является двойной путь AreaName / ControllerName в URL, например, / Blog / Blog / выше

Не имея полного четкого понимания маршрутизации, как я могу настроить маршрутизацию, чтобы не отображать AreaName?

EDIT:

Я пытаюсь уменьшить объем работы с маршрутами, так как они влияют друг на друга (т.е. требуют определенного порядка) и могут вызвать серьезные головные боли :-) При преобразовании существующего приложения веб-формы в MVC я преобразовал пару основные разделы, каждый из них имеет один контроллер и достаточное количество View / Actions, и хотя большая часть доступа к данным представляет собой код в сборках, количество классов Model / ViewData растет ... В настоящее время я создаю подпапки в Root Папки Models / Views для этих разделов (или областей) и надеялись, что создание областей будет работать так же, за исключением того, что будет организован код (с использованием базового маршрута, охватывающего Район) Любой комментарий по этому поводу?

Ответы [ 2 ]

20 голосов
/ 21 апреля 2010

Внутри папки каждой области вы увидите файл *AreaName*AreaRegistration.cs. Здесь хранятся правила маршрутизации области. По умолчанию, поскольку они генерируются, они будут содержать имя области впереди всего остального. Проблема в том, что если вы удалите имя области «папка» из маршрута, маршрут перехватит все «стандартные» {controller} / { действие} / {id} запросов. Что, очевидно, не то, что вы хотите ..

Чтобы преодолеть это, вы можете добавить фильтры регулярных выражений в маршруты на основе имен контроллеров, присутствующих в этом маршруте. Недостаток? Вы не сможете иметь два контроллера с одинаковым именем в приложении (по крайней мере, не используя стандартный маршрут. Вы всегда можете придумать другой маршрут для доступа к ним :))

В конце концов .. Имея эту структуру:

/ Areas
/Areas/Blog/Controllers/BlogController.cs
/Areas/Blog/Controllers/FeedController.cs
/Areas/User/Controllers/UserController.cs
/Controllers/PageController.cs

То, что вы должны иметь, вот что: В BlogAreaRegistration.cs:

context.MapRoute(
    "Blog_default",
    "{controller}/{action}/{id}",
    new { action = "Index", id = UrlParameter.Optional },
    new { controller = "(Blog|Feed)" }
);

В UserAreaRegistration.cs:

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

В Global.asax.cs:

public static void RegisterRoutes(RouteCollection routes)
{
    context.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterRoutes(RouteTable.Routes);
}

Обратите внимание, что в области global.asax регистрация на первом месте! :)

UPD: На основании вашего вопроса обновления: Здесь есть одна важная вещь, которую вы должны принять во внимание, если будете использовать области: если у вас есть межобластная ссылка, вам также нужно будет указать название области в ссылке. Э.Г.

<%: Html.ActionLink("Link text", "Action", "Controller", new { area = "Blog", id = 4, title = "page-title" }); %>

Вы поняли идею.

Что касается нескольких моделей / представлений, в данный момент я следую за структурой, подобной этой

/ Code / // помощник, классы расширений, которые не перемещены в библиотеки
/ Модели / Данные / // Классы EF + классы проверки здесь
/ Models / ViewModels / {controller} / // просмотр моделей, сохраненных для каждого контроллера

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

1 голос
/ 11 мая 2010

Просто чтобы ответить на ваш оригинальный вопрос, если кто-то еще читает это:

Не называйте свой блог контроллера по умолчанию. Вот почему вы получаете блог / блог {область / контроллер}. Вы можете либо дать ему совершенно другое имя: то есть, блог / просмотр, блог / посты, блог / недавний и т. Д., Или, по умолчанию, как home. в этом случае, если у вас также есть дом в ваших контроллерах вне зоны действия, вы захотите указать пространство имен вашего контроллера по умолчанию:

routes.MapRoute("Default",
  "{controller}/{action}/{id}",
  new { controller = "Home", action = "Index", id = UrlParameter.Optional},
  new[] { *appname*.Controllers" });

Это обеспечит переход «/» и «/ blog» к соответствующему «домашнему» контроллеру. Если вы ищете дубликат ошибки домашнего контроллера, вы найдете больше об этом.

...