Подтвердить что ты не робот

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

Я просто получить ресурс не может найти ошибку. Все очень недоумение! Надеюсь, кто-то может помочь...

4b9b3361

Ответ 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

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