ASP MVC4 Поиск подходящего метода в контроллерах с одинаковыми именами в разных областях - PullRequest
0 голосов
/ 08 марта 2012

Я видел несколько похожих вопросов, но обнаружил, что у меня другая проблема.

У меня есть проект MVC4 с контроллерами в базовом проекте и 3 областями.Каждая область содержит контроллер с именем AdminController и метод List.

Моя проблема заключается в том, что когда я использую ссылку для перехода к методу, список всегда проходит через один и тот же контроллер (например, AdminController в области Users), но возвращаемое представление верное.

Структура проекта выглядит следующим образом:

  • Mimbre.Administration (веб-проект mvc4)
    • Области
      • Содержание
        • Контроллеры
          • AdminController
        • Модели
        • Представления
          • Администратор
            • List.chtml -ContentsAreaRegistration.cs
      • Logs
        • Контроллеры
          • AdminController
        • Модели
        • Просмотры
          • Администратор
            • List.chtml
        • LogsAreaRegistration.cs
      • Пользователи
        • Контроллеры
          • AdminController
        • Модели
        • Просмотры
          • Admin
            • List.chtml
        • UsersAreaRegistration.cs
    • Контроллеры (базовыеproject)
    • Views (базовый проект)

Классы для регистрации области содержат такой метод RegisterArea (с соответствующим именем и пространством имен в соответствии с текущей областью):

   public override void RegisterArea(AreaRegistrationContext context) {
        context.MapRoute(
            "Contents_default",
            "Contents/{controller}/{action}/{id}",
            new { action = "Index", id = UrlParameter.Optional },
            new string[] { "Mimbre.Administration.Areas.Contents.Controllers" }
        );
    }

Global.asax содержит метод для регистрации маршрутов для базового проекта

        public static void RegisterRoutes(RouteCollection routes) {

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        AreaRegistration.RegisterAllAreas();

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new string[]{"Mimbre.Administration.Controllers"}
        );
    }

В index.chtml (в базовом проекте) я создал ссылки на метод List каждой области:

<a href="@Url.Action("List", "Admin", new { area = "Contents"})" >Contents list</a>
<a href="@Url.Action("List", "Admin", new { area = "Logs"})" >Logs list</a>
<a href="@Url.Action("List", "Admin", new { area = "Users"})" >Users list</a>

В сгенерированном html эти ссылки выглядят так:

<a href="/Contents/Admin/List/">Contents list</a>
<a href="/Logs/Admin/List/">Logs list</a>
<a href="/Users/Admin/List/">Users list</a>

Я думаю, что эти ссылки правильные, проблема в том, что любая нажатая ссылка всегда ведет меня через метод List в области AdminController в области Users, метод List в AdminController других областей никогда не выбирается.

Эту проблему можно решить, переименовав имя контроллера, уникальное имя для каждой области, но мне действительно нужно сохранить одинаковое имя контроллера во всех областях,любая идея???

Заранее спасибо !!!

Ответы [ 2 ]

2 голосов
/ 09 марта 2012

Наконец-то я смогла смоделировать твою проблему. Единственный способ получить тот же вывод, что и у вас (не имеет значения, к какой области вы пытаетесь получить доступ, но при этом получаете доступ к тому же контроллеру пользователей и отвечает с правильным видом), это когда вы регистрируете Area с неправильными пространствами имен контроллеров. 1001 *

/ Админ / Главная / Список маршрутов:

namespace SandboxMvcApplication.Areas.Admin.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult List()
        {
            ViewBag.Message = "You've acessed Admin/List";

            return View();
        }
    }
}

/ Администратор / Главная / Список:

@{
    ViewBag.Title = "List";
}

<h1>Admin</h1>

<h2>@ViewBag.Message</h2>

Регистрация администратора:

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "Admin_default",
        "Admin/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional },
        new string[] { "SandboxMvcApplication.Areas.Admin.Controllers" }
    );
}

/ Пользователь / Домой / Список маршрутов:

public class HomeController : Controller
{
    public ActionResult List()
    {
        ViewBag.Message = "You've accessed User/List";

        return View();
    }
}

/ Пользователь / Домой / Вид списка:

@{
    ViewBag.Title = "List";
}

<h1>User</h1>

<h2>@ViewBag.Message</h2>

Регистрация в пользовательской зоне:

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "User_default",
        "User/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional },
        new string[] { "SandboxMvcApplication.Areas.Admin.Controllers" }
    );
}

При такой конфигурации мои выходы:

  1. / Администратор / Главная / Список

    Администратор

    Вы обращались к администратору / списку

  2. / Пользователь / Главная / Список

    Пользователь

    Вы обращались к администратору / списку

Обратите внимание, что первое слово работает нормально (гарантируя, что правильное представление было отображено, но с неверными данными, поступающими из списка действий).

Если я исправлю пространство имен контроллера пользователя в UserAreaRegistration («SandboxMvcApplication.Areas.User.Controllers»), все будет отлично!

Проверьте, может ли это вам помочь, или попробуйте явно поместить ваши пространства имен в нужный контроллер. Вы также можете проверить правильность пространства имен для контроллера Admins.

0 голосов
/ 08 июня 2012

Вам необходимо добавить еще одну настройку к регистрации маршрута. Это предотвратит поиск DefaultControllerFactory контроллера в непредусмотренных областях.

        routes.MapRoute( 
        name: "Default", 
        url: "{controller}/{action}/{id}", 
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
        namespaces: new string[]{"Mimbre.Administration.Controllers"} 
    ).DataTokens["UseNamespaceFallback"] = false; 
...