Как правильно использовать Html.ActionLink с ASP.NET MVC 4 Области
Недавно я обнаружил Области в ASP.NET MVC 4, которые я успешно выполнил, но я столкнулся с проблемами с @Html.ActionLink
помощник в моих взглядах Бритвы. URL-адрес, который генерирует этот помощник, всегда, по-видимому, относится к URL-адресу текущей страницы.
У меня есть мой веб-сайт, настроенный в IIS 7 (Win7) в качестве виртуального каталога приложения в /Foo
.
У меня две зарегистрированные области: Admin и Blogs. У меня есть код по умолчанию в файлах AdminAreaRegistration.cs
и BlogsAreaRegistration.cs
. Я добавил namespaces = new[] { "MvcProject.Controllers" }
к значениям по умолчанию RouteConfig по умолчанию:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {
controller = "Home", action = "Index", id = UrlParameter.Optional,
namespaces = new[] { "MvcProject.Controllers" }
}
);
}
}
Когда я перехожу на домашнюю страницу для своего сайта: http://localhost/Foo
, он правильно загружает страницу "home" для моего сайта. На этом этапе все ссылки действий имеют свои правильные URL-адреса.
Пример кода из MvcProject/Views/Shared/_Layout.cshtml
<h2>Main Navigation</h2>
<ul>
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("Blogs", "Index", "Blogs/Home")</li>
<li>@Html.ActionLink("Admin", "Index", "Admin/Home")</li>
</ul>
Это правильно отображает HTML как:
<h2>Main Navigation</h2>
<ul>
<li><a href="/Foo">Home</a></li>
<li><a href="/Foo/Blogs/Home"></li>
<li><a href="/Foo/Admin/Home"></li>
</ul>
Когда я просматриваю браузер в браузере, например, этот URL правильно загружается в браузере: /Foo/Blogs/Home
.
Теперь ссылки в моей основной навигации меняют URL-адреса на:
<h2>Main Navigation</h2>
<ul>
<li><a href="/Foo/Blogs/Home">Home</a></li>
<li><a href="/Foo/Blogs/Blogs/Home"></li>
<li><a href="/Foo/Blogs/Admin/Home"></li>
</ul>
Обратите внимание, что "Блоги/" добавляется к имени виртуального каталога IIS, поэтому /Foo/Blogs/Home
теперь /Foo/Blogs/Blogs/Home
.
Контроллеры и представления отлично обрабатываются, только вызовы @Html.ActionLink
в моем представлении MvcProject/Views/Shared/_Layout.cshtml
работают не так, как я ожидал.
Похоже, что я пропустил что-то тривиальное, но никакой поиск не получил ответа. Каждое сообщение в блоге и учебник, который я нашел для реализации областей в ASP.NET MVC4, не упоминает об изменениях поведения @Html.ActionLink
.
Ответы
Ответ 1
Я ненавижу отвечать на свой вопрос, но @Matt Bodily поставил меня на правильный путь.
Метод @Html.Action
фактически вызывает контроллер и отображает представление, так что это не сработает для создания фрагмента HTML в моем случае, поскольку это вызвало вызов рекурсивной функции, приводящий к исключению StackOverflowException. @Url.Action(action, controller, { area = "abc" })
действительно возвращает URL-адрес, но я, наконец, обнаружил перегрузку Html.ActionLink
, которая обеспечила лучшее решение для моего случая:
@Html.ActionLink("Admin", "Index", "Home", new { area = "Admin" }, null)
Примечание: , null
является значительным в этом случае, чтобы соответствовать правильной сигнатуре.
Документация: @Html.ActionLink(LinkExtensions.ActionLink)
Документация для этой конкретной перегрузки:
LinkExtensions.ActionLink(контроллер, действие, текст, RouteArgs, HtmlAttributes)
Было сложно найти документацию для этих помощников. Я, как правило, искал "Html.ActionLink", когда мне, вероятно, следовало искать "LinkExtensions.ActionLink", если это поможет кому угодно в будущем.
По-прежнему отмечаем ответ Мэтта как ответ.
Изменить: нашел еще один помощник HTML, чтобы решить эту проблему:
@Html.RouteLink("Admin", new { action = "Index", controller = "Home", area = "Admin" })
Ответ 2
Как я перенаправляю область, добавляю ее как параметр
@Html.Action("Action", "Controller", new { area = "AreaName" })
для части href ссылки, которую я использую
@Url.Action("Action", "Controller", new { area = "AreaName" })
Ответ 3
Просто чтобы добавить свой бит:
Помните, что вам нужно иметь как минимум 2 области в вашем приложении MVC для работы routeValues: { area="" }
; в противном случае значение области будет использоваться как параметр строки запроса, и ссылка будет выглядеть так: /?area=
Если у вас нет не менее двух областей, вы можете исправить это поведение:
1. Редактирование маршрута по умолчанию в RouteConfig.cs
следующим образом:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
OR
2. Добавление фиктивной области в проект MVC.