Было найдено несколько типов, которые соответствуют контроллеру с именем 'Home'

318

В настоящее время у меня есть два несвязанных проекта MVC3, размещенных онлайн.

Один работает нормально, другой не работает, выдавая ошибку:

Найдено несколько типов, соответствующих контроллеру с именем «Home». Это может произойти, если маршрут, обслуживающий этот запрос ('{controller} / {action} / {id}'), не указывает пространства имен для поиска контроллера, соответствующего запросу.

Если это так, зарегистрируйте этот маршрут, вызвав перегрузку метода MapRoute, который принимает параметр namespaces.

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

ftpFolderA2 / foo.com

ftpFolderA2 / bar.com

foo.com работает нормально, я публикую свое приложение в локальной файловой системе, затем отправляю по FTP содержимое, и оно работает.

Когда я загружаю и пытаюсь запустить bar.com, вышеуказанная проблема не позволяет мне использовать мой сайт. Все пока foo.com все еще работает .

Bar.com ищет из контроллеров ВЕЗДЕ внутри ftpFolderA2, и поэтому он находит другой HomeController? Как я могу сказать, чтобы он смотрел только в папке Controller как надо?

Факты:

  1. Не используя области. Это два ПОЛНОСТЬЮ не связанных проекта. Я помещаю каждый опубликованный проект в каждую соответствующую папку. Ничего особенного.
  2. Каждый проект имеет только 1 HomeController.

Может кто-нибудь подтвердить, что это проблема?

Только боливийский здесь
источник
Очень неясный вопрос. Вы используете области? Проблема возникает локально?
Дарин Димитров
1
@Darin: отредактировал эту информацию.
Только боливийский здесь

Ответы:

473

Это сообщение об ошибке часто появляется, когда вы используете области, и у вас есть одинаковое имя контроллера внутри области и корня. Например, у вас есть два:

  • ~/Controllers/HomeController.cs
  • ~/Areas/Admin/Controllers/HomeController.cs

Чтобы решить эту проблему (как подсказывает вам сообщение об ошибке), вы можете использовать пространства имен при объявлении маршрутов. Итак, в определении основного маршрута Global.asax:

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

и в вашем ~/Areas/Admin/AdminAreaRegistration.cs:

context.MapRoute(
    "Admin_default",
    "Admin/{controller}/{action}/{id}",
    new { action = "Index", id = UrlParameter.Optional },
    new[] { "AppName.Areas.Admin.Controllers" }
);

Если вы не используете области, кажется, что оба ваших приложения размещены в одном и том же приложении ASP.NET, и возникают конфликты, потому что у вас одинаковые контроллеры, определенные в разных пространствах имен. Вам нужно будет настроить IIS для размещения этих двух как отдельных приложений ASP.NET, если вы хотите избежать подобных конфликтов. Попросите вашего хостинг-провайдера об этом, если у вас нет доступа к серверу.

Дарин димитров
источник
Я не использую области вообще. Это два совершенно не связанных между собой приложения, которые находятся в отдельной папке внутри корневой папки FTP. Может быть, мое приложение ищет контроллеры MVC везде, где это возможно, и это может произойти и для других домашних контроллеров. Как я могу сказать, чтобы он нигде не смотрел, но имел собственную папку Controller и не обращал внимания на остальные?
Только боливийский здесь
2
@ SergioTapia, похоже, они довольно связаны с вашими приложениями. Ваш хостинг-провайдер поместил их в одно и то же приложение ASP.NET. Вам нужно будет попросить его разделить их в IIS как отдельные экземпляры, иначе у вас будет много проблем.
Дарин Димитров
13
Спасибо. В ASP MVC 4.0 вам нужно передать именованный аргумент, как пространства имен: new [] {"AppName.Areas.Admin.Controllers"}
om471987
1
+1 - хорошо работает. Я не понимал, что там есть отдельная зона для регистрации маршрута. Везде, куда бы я ни посмотрел, кажется, что есть качественный ответ от Дарина :)
Travis J
1
Если вы используете области и хотите использовать пространство имен для контроллеров, вам необходимо указать пространство имен как внутри, так и снаружи маршрутов . Только пространство имен маршрутов области все еще дало мне эту проблему.
Гэвин Уорд
528

Вот еще один сценарий, в котором вы можете столкнуться с этой ошибкой. Если вы переименуете свой проект так, что имя файла сборки изменится, возможно, у вас будет две версии сборки ASP.NET, которые будут воспроизводить эту ошибку.

Решение состоит в том, чтобы перейти к вашей binпапке и удалить старые библиотеки. (Я попробовал «Перестроить проект», но он не удалил их, поэтому обязательно проверьте, binчтобы они исчезли)

Кирк Волл
источник
1
Другой вариант этой ошибки - когда вы используете resharper и используете некоторые «авто» опции рефакторинга, которые включают изменение имени пространства имен. Это было то, что случилось со мной.
Себастьян 506563
5
Если вы получаете это из службы приложений Azure, перейдите по адресу https: // <your_app_name_here> .scm.azurewebsites.net / DebugConsole, чтобы войти в систему и удалить файлы.
Том Блоджет
5
Thx это было проблемой для меня. Я создал «новый» проект, скопировав / вставив существующий проект в новую папку; старая сборка dll пришла, удалив папку bin, вытер ее чистой
brando
Я получил это при перемещении файлов моего проекта на второй диск. Очистка папки bin решает ее. Странная чертова вещь.
Роберто Бонини
Ну, это была очень досадная ошибка с очень простым исправлением. Спасибо!
Трой Гросфилд
63

В MVC4 и MVC5 это немного отличается, используйте следующее

/App_Start/RouteConfig.cs

namespace MyNamespace
{
    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[] {"MyNamespace.Controllers"}
            );
        }
    }
}

и в районах

context.MapRoute(
                "Admin_default",
                "Admin/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional },
                new[] { "MyNamespace.Areas.Admin.Controllers" }
            );
разработчик
источник
39

Посмотрите это ... http://www.asp.net/mvc/videos/mvc-2/how-do-i/aspnet-mvc-2-areas

Тогда эта картина (надеюсь, вам понравятся мои рисунки)

введите описание изображения здесь

Том
источник
Решил вопрос ..! :)
Аруна
1
@ppumkin расскажи это слепому программисту. Текст может быть прочитан читателями экрана, хотя
Карлос Муньос
Привет, Карлос. Да, я понимаю ситуацию. Это уже сложно объяснить людям без видимости. Я даже не уверен, что какое-либо вспомогательное программное обеспечение сможет хорошо описать то, что происходит на картинке, для любого тела. Обращает на себя внимание, что ответ, вероятно, должен содержать текст, по крайней мере, пытаясь описать, что происходит.
Петр Кула
32

То, что говорили другие, правильно, но для тех, кто все еще сталкивается с той же проблемой:
в моем случае это произошло потому, что я скопировал другой проект и переименовал его во что-то еще, НО предыдущие выходные файлы в binпапке все еще были там ... И, к сожалению, Build -> Clean Solutionпосле переименования ударил проект и его Namespaces не удаляет их ... так что удаление их вручную решило мою проблему!

Доктор TJ
источник
2
Ваше предложение спасло меня
Абхиманью
1
я тоже, спасибо, чистые дела на самом деле означают чистые, grrrr
katibaer
1
Спасибо @DrTJ Это оооочень расстраивает! Вы ожидаете, что чертовски чистый процесс сработает, а ожидания - корень неудачи. Это спасло меня от выдергивания волос!
Майк
28

в bin/папке вашего проекта

убедитесь, что у вас есть только ваша PROJECT_PACKAGENAME.DLL

и удалите ANOTHER_PROJECT_PACKAGENAME.DLL

которые могут появиться здесь по ошибке или вы просто переименуете свой проект

Sruit A.Suk
источник
2
Именно моя проблема. Спасибо.
Детилиум
Работал на меня! Thnks!
Эяль
Я сменил название сборки и в мусорном баке сидели старые библиотеки. Спасибо
APC
Спасибо! Я не могу поверить, что пропустил что-то такое простое.
Ваш
25

Проверьте папку bin, если есть другой файл dll, который может конфликтовать с классом homeController.

Амир Шреста
источник
7
Это немного меня, когда я копировал проект и переименовывал его ... старый проект с именем dll все еще был в корзине, очистка не удаляла его ... Мне пришлось удалить его вручную!
Пол Захра
2
Это было проблемой для меня. Коллега по ошибке добавил ссылку из одного интерфейсного проекта на другой, создавшую эту проблему. Он удалил ссылку, таким образом Visual Studio также удалила файлы DLL на своем диске. Я вытащил обновление из Git, ссылки пропали, но файлы dll остались даже после очистки. Просто потому, что мой VS больше не видел ссылку. Но при запуске IIS видел файлы и использовал их. Удаление их с моего диска помогло.
Еронимо
14

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

ControllerBuilder.Current
     .DefaultNamespaces.Add("YourApp.Controllers");
Бен Фостер
источник
Это был случай для меня. Если у вас действительно есть несколько контроллеров с одним и тем же именем, это может понадобиться после того, как вы добавили пространства имен в определения вашего маршрута. Например, для вашей домашней страницы, где контроллер и область явно не выбраны путем.
Джейсон Бек
В проекте, над которым я работаю, у нас есть главный офис под ключ с областями для индивидуальной работы с клиентом. Каждый из них имеет контроллер настроек. Этот ответ является отличной альтернативой необходимости определения маршрута для контроллера настроек для каждой области.
Дерек Дин
7

Даже если вы не используете области, вы все равно можете указать в RouteMap, какое пространство имен использовать

routes.MapRoute(
    "Default",
    "{controller}/{action}",
    new { controller = "Home", action = "Index" },
    new[] { "NameSpace.OfYour.Controllers" }
);

Но похоже, что проблема заключается в том, как ваши два приложения настроены в IIS

запруживать
источник
7

У меня просто была эта проблема, но только когда я публиковал на своем веб-сайте, на моей локальной отладке она работала нормально. Я обнаружил, что должен был использовать FTP с моего веб-хоста, зайти в мой каталог публикации и удалить файлы в папке BIN, при их локальном удалении ничего не происходило при публикации.

Mech0z
источник
Это было исправление для меня. Мой профиль публикации не удалял файлы, не представленные локально, поэтому мое приложение подобрало старые dll в дополнение к новым и обнаружило дубликаты типов.
Форма
1
Я изменил название своего проекта и рефракторил все файлы, но затем я получил эту ошибку. Удаление папки bin работало для меня тоже.
Мауро Вальвано
6

Может быть другой случай с областями, даже если вы выполнили все этапы маршрутизации в областях (например, предоставление пространств имен в глобальной таблице маршрутизации), а именно:

Возможно, вы не обернули свои глобальные контроллеры в «пространство имен», которое вы указали при маршрутизации.

Например:

Сделано это:

public class HomeController : Controller
{

Вместо того:

namespace GivenNamespace.Controllers
{
   public class HomeController : Controller
   {
Т Гупта
источник
Да. Недостаточно просто предоставить пространство имен в MapRoute. Предоставленное здесь пространство имен должно соответствовать пространству имен класса контроллера. Теперь это работает!
DanKodi
6

Вы также можете получить ошибку 500, если добавите свою собственную сборку, содержащую ApiController, переопределив GetAssemblies объекта DefaultAssembliesResolver, и он уже находится в массиве из base.GetAssemblies ()

Дело в точке:

public class MyAssembliesResolver : DefaultAssembliesResolver
{
    public override ICollection<Assembly> GetAssemblies()
    {
        var baseAssemblies = base.GetAssemblies();

        var assemblies = new List<Assembly>(baseAssemblies);

        assemblies.Add(Assembly.GetAssembly(typeof(MyAssembliesResolver)));

        return new List<Assembly>(assemblies);
    }
}

Если приведенный выше код находится в той же сборке, что и ваш контроллер, эта сборка будет в списке дважды и выдаст ошибку 500, поскольку Web API не знает, какую из них использовать.

Аллан Элдер
источник
6

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

 routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new[] { string.Format("{0}.Controllers", BuildManager.GetGlobalAsaxType().BaseType.Assembly.GetName().Name) }
        );
Xtremexploit
источник
1
отличное решение, если у вас есть одинаковые контроллеры в нескольких проектах
Рави Ананд
4

Возникла такая же проблема и ничего не помогло. Проблема в том, что у меня фактически нет дубликатов, эта ошибка появляется после переключения пространства имен проекта с MyCuteProjectна MyCuteProject.Web.

В итоге я понял, что источником ошибки является global.asaxфайл - разметка XML, а не .cs-codebehind. Проверьте пространство имен в нем - это помогло мне.

Арман Хайотс
источник
2

Я просто удалил папку «Bin» с сервера и скопировал мой bin на сервер, и моя проблема решена.

Джавад Хемати
источник
2

В Route.config

пространства имен: new [] {"Appname.Controllers"}

Awais
источник
1

Мы обнаружили, что получили эту ошибку, когда в нашей сборке возник конфликт, который выглядел как предупреждение.

Мы не получили детали, пока не увеличили Visual Studio -> Tools -> Options -> Projects and Solutions -> Build and Run -> MSBuild - подробность сборки проекта.

Наш проект представляет собой веб-приложение .net v4, и возник конфликт между System.Net.Http (v2.0.0.0) и System.Net.Http (v4.0.0.0). Наш проект ссылался на версию v2 файла из пакета (включенного с помощью nuget). Когда мы удалили ссылку и добавили ссылку на версию v4, сборка работала (без предупреждений), и ошибка была исправлена.

AnthonyJ
источник
1

Другой вариант этой ошибки - когда вы используете resharper и используете некоторые «авто» опции рефакторинга, которые включают изменение имени пространства имен. Это то, что случилось со мной. Чтобы решить проблему с таким сценарием, удалите папкуbin

Себастьян 506563
источник
Это случилось со мной, когда я скопировал содержимое одного проекта поверх содержимого другого. Мне пришлось удалить определенные файлы из папки bin
Adriaan Davel
1

Щелкните правой кнопкой мыши проект и выберите «Очистить проект». Или же полностью очистите каталог bin и затем пересоберите заново. Это должно очистить от любых оставшихся сборок из предыдущих сборок

VivekDev
источник
1

Некоторое время в одном приложении эта проблема также возникает. В этом случае установите флажок при публикации приложения. введите описание изображения здесь

Уманг Патва
источник
1

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

Хьюго
источник
0

Если вы работаете в Episerver или другой CMS на основе MVC, вы можете обнаружить, что это конкретное имя контроллера уже заявлено.

Это случилось со мной при попытке создать контроллер под названием FileUpload.


источник
0

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

у меня это будет полезно для вас.

Проектное решение

Сатиш Кумар Сонкер
источник
0

У меня есть два проекта в одном решении с тем же именем контроллера. Я удалил вторую ссылку проекта в первом проекте, и проблема решена

Кашиф Фараз
источник
0

Я обнаружил, что эта ошибка может возникать на традиционном веб-сайте ASP.NET при создании контроллера в каталоге, отличном от App_Code (иногда Visual Studio предотвращает это).

Он устанавливает тип файла «Компилировать», в то время как любой код, добавленный к «App_Code», устанавливается в «Содержимое». Если вы копируете или перемещаете файл в App_Code, тогда он все еще установлен как «Компилировать».

Я подозреваю, что это как-то связано с работой проекта веб-сайта, так как проекты веб-сайта не выполняют никаких операций сборки. Очистка папки bin и изменение ее на «Content», кажется, исправят это.

Кертис Уайт
источник