ASP.NET MVC Области: как скрыть имя "Area" в URL?

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

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

RootUrl/AreaName/ControllerName/ActionName

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

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

EDIT:

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

Ответы

Ответ 1

Внутри каждой папки области вы увидите файл *AreaName*AreaRegistration.cs. Здесь хранятся правила маршрутизации области. По умолчанию, поскольку они сгенерированы, они будут содержать название области впереди всего остального. Проблема заключается в следующем: если вы удалите имя области "папка" с маршрута, маршрут поймает все "стандартные" {controller}/{ action}/{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" }); %>

Вы получаете идею.

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

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

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

Ответ 2

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

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

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

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