ASP.NET MVC `Html.ActionLink` между "областями"
Я добавил новую область в мой проект MVC3, и я пытаюсь связать ее с страницей _Layout в новый. Я добавил область под названием "Admin", у которой есть контроллер "Meets".
Я использовал дизайнера визуальной студии, чтобы добавить область, чтобы иметь правильный класс регистрации области и т.д., а файл global.asax регистрирует все области.
Однако, когда я использую следующие 2 ссылки действий на странице в корне, я сталкиваюсь с несколькими проблемами:
@Html.ActionLink("Admin", "Index", "Meets", new { area = "Admin" }, null)
@Html.ActionLink("Admin", "Index", "Meets", new { area = "" }, null)
При щелчке обеих ссылок я попадаю в контроллер Meets в области Admin, где приложение затем отправляет ошибку, заявляя, что не может найти страницу Index (даже если страница Index присутствует в папке Views в Подкатегория области.
Ссылка для первой ссылки выглядит следующим образом:
http://localhost/BCC/Meets?area=Admin
И href для второй ссылки выглядит так:
http://localhost/BCC/Meets
Также, если я нажму ссылку, которую я ожидаю создать:
http://localhost/BCC/Admin/Meets
Я просто получить ресурс не может найти ошибку. Все очень недоумение! Надеюсь, кто-то может помочь...
Ответы
Ответ 1
Я понял это - я создал новый тестовый проект и сделал то же самое, что и раньше, и это сработало... затем, после дальнейшего осмотра всех маршрутов, связанных между двумя проектами, я нашел несоответствие.
В файле global.asax в моем приложении BCC появилась строка изгоев кода, которая необъяснимо появилась:
public static void RegisterRoutes(RouteCollection routes)
{
// Problem here
routes.Clear();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
Как вы можете видеть, где мой комментарий, в какой-то момент я поместил маршруты. Очистить() в начале RegisterRoutes, что означало после того, как я зарегистрировал Области в Application_Start, я тут же очистил, что Я только что зарегистрировался.
Спасибо за помощь... это в конечном итоге привело к моему спасению!
Ответ 2
Странно. Шаги, которые работали отлично для меня:
- Создайте новое приложение ASP.NET MVC 3 с использованием шаблона Visual Studio по умолчанию
- Добавьте область под названием
Admin
с помощью конструктора Visual Studio, щелкнув правой кнопкой мыши по проекту
-
Добавить новый контроллер в ~/Areas/Admin/Controllers/MeetsController
:
public class MeetsController : Controller
{
public ActionResult Index()
{
return View();
}
}
-
Добавьте соответствующее представление ~/Areas/Admin/Views/Meets/Index.cshtml
-
В макете (~/Views/Shared/_Layout.cshtml
) добавьте ссылки:
@Html.ActionLink("Admin", "Index", "Meets", new { area = "Admin" }, null)
@Html.ActionLink("Admin", "Index", "Meets", new { area = "" }, null)
- Запустите приложение.
Отрисованный HTML для якорей:
<a href="/Admin/Meets">Admin</a>
<a href="/Meets">Admin</a>
Как и ожидалось, первая ссылка работает, а вторая - нет.
Итак, какая разница с вашей настройкой?
Ответ 3
Другой вариант - использовать RouteLink() вместо ActionLink(), который вообще обходит регистрацию области:
Версия ActionLink:
Html.ActionLink("Log Off", "LogOff", "Account", new { area = "" }, null)
Версия RouteLink:
Html.RouteLink("Log Off", "Default",
new { action = "LogOff", controller = "Account" })
Второй параметр - это "Имя маршрута", которое зарегистрировано в Global.asax.cs и в разных подклассах AreaRegistration. Чтобы использовать "RouteLink" для связи между различными областями, вам нужно указать только правильное имя маршрута.
В следующем примере показано, как я буду генерировать три ссылки на разные области из общего частичного файла, который работает правильно независимо от того, в какой области я "в" (если есть):
@Html.RouteLink("Blog", "Blog_default",
new { action = "Index", controller = "Article" })
<br/>
@Html.RouteLink("Downloads", "Download_default",
new { action = "Index", controller = "Download" })
<br/>
@Html.RouteLink("About", "Default",
new { action = "Index", controller = "About" })
Счастливое кодирование!
Ответ 4
Убедитесь, что класс AdminAreaRegistration
выглядит следующим образом:
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
и что у вас это есть в Global.asax.cs
:
protected void Application_Start()
{
... // ViewEngine Registration
AreaRegistration.RegisterAllAreas();
... // Other route registration
}
Ответ 5
Я решил эту проблему, выполнив следующее.
В моем Global.asax.cs у меня есть
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
}
protected void Application_Start()
{
//Initialise IoC
IoC.Initialise();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
В моей PublicAreaRegistration.cs(Public Area) у меня есть
public class PublicAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Public";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute("Root", "", new { controller = "Home", action = "Index" });
context.MapRoute(
"Public_default",
"Public/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
, new[] { "<Project Namespace here>.Areas.Public.Controllers" }
);
}
}
В моем AuthAreaRegistration.cs(Area for Restricted access) у меня есть
public class AuthAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Auth";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Auth_default",
"Auth/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
И, наконец, мои ссылки на моих *.cshtml страницах будут похожи на
1) @Html.ActionLink( "Выход из системы", "LogOff", новый {area = "Public", controller = "Home" })
или
2) @Html.ActionLink( "Admin Area", "Index", new {area = "Auth", controller = "Home" })
Надеюсь, это сэкономит время на исследования! Кстати, я говорю о MVC3 здесь.
Kwex.
Ответ 6
Это может быть не так для большинства разработчиков, но я столкнулся с этой проблемой, когда добавил свою первую область и не создал свое решение. Как только я построю свое решение, ссылки начали правильно заполняться.