У меня возникла проблема с разрешением 404 ответов в моем проекте Asp.Net MVC 4. Он построен в VS2012, ориентированном на 4.5.404 на контроллерах во внешних сборках
У меня есть предварительно скомпилированные представления и контроллеры, встроенные в автономные библиотеки DLL. Я могу динамически загружать библиотеки DLL и проверять их из моего основного проекта, даже вызывать методы на них; однако, похоже, что MVC Framework не знает контроллеров. Я рядом, но чего-то не хватает.
Справочная информация о контроллерах и представлений
контроллеры встроены в отдельный проект MVC и наследовать от Controller
. Ничего интересного не происходит. Представления используют RazorGenerator и становятся классами, которые живут в проекте.
Результатом проекта является DLL, которая правильно содержит контроллеры и представления.
DLL реализует определенный интерфейс, мы будем называть его IPlugin
в отдельном классе (не являющемся частью контроллера) в библиотеке.
Загрузка библиотеки DLL
Запуск от имени администратора в Visual Studio я компилирую мое приложение, которое организовано под IIS. С построенным проектом я бросаю DLL плагина в каталог «Плагины». Без отладки (это становится важным позже) я открываю IE и перехожу на сайт. Обратите внимание, что на этом этапе приложение было создано, но никогда не запускается, поэтому запускаются события запуска. Все, что я могу сделать, все равно остается неизменным, если я повторно использую пул приложений.
У меня есть Startup
класса с двумя методами, PreStart
и PostStart
и вызывать методы с использованием WebActivator.PreApplicationStartMethod
и WebActivator.PostApplicationStartMethod
соответственно.
PreStart
где я сделать следующее:
- Получить список всех плагинов DLL, в моем каталоге «Plugins»
- Скопируйте все плагины
AppDomain.CurrentDomain.DynamicDirectory
- загрузить тип ... если она содержит
IPlugin
я тогда- Добавить сборку в BuildManager
- Зов некоторые из методов в классе, что IMP lements IPlugin
В 'PostStart' Я делаю это немного кода (на основе кода из RazorGenerator.Mvc):
foreach (var assembly in Modules.Select(m=>m.Value))
{
var engine = new PrecompiledMvcEngine(assembly)
{
UsePhysicalViewsIfNewer = HttpContext.Current.Request.IsLocal
};
ViewEngines.Engines.Insert(0, engine);
VirtualPathFactoryManager.RegisterVirtualPathFactory(engine);
}
Modules
в этом контексте является пара ключ/значение, где значения - это загруженные сборки. Цель этого кода - убедиться, что MVC осведомлен о представлениях, добавив механизм просмотра для каждой сборки, который знает, как разрешить представления (это часть RazorGenerator).
Как я знаю, что я Close (но явно не достает сигару)
IPlugin
определяет метод, называемый RegisterRoutes
, где, как вы уже догадались, маршруты должны быть зарегистрированы для тех, кто реализует интерфейс. Я вызываю этот метод в PreStart
и добавляются маршруты - я подтвердил, что они существуют в моей таблице маршрутов. Например, на маршруте, определенный в мой плагин, созданный с помощью динамического вызова метода во время PreStart
, я вижу что-то вроде этого как DataToken при рассмотрении моих маршрутов:
Namespaces = Plugin.Name.Controllers
Таким образом, маршрут зарегистрирован, сборка загружена, я проверил, что DLL правильно скопирована в DynamicDirectory AppDomain. Я могу вызвать участников классов, которые динамически загружаются во время выполнения. Но когда я перехожу к URL-адресу, который соответствует маршруту , я получаю 404. Это не a «не удалось найти местонахождение» YSOD, это больше похоже на то, что вы не обнаружили контроллер вообще.
Вот часть, которая смущает меня из-за меня: если в данный момент, ничего не делая, я возвращаюсь в Visual Studio и нажимаю F5 ... все работает.
Это похоже на то, что Visual Studio каким-то образом узнает о контроллере, который я не могу определить, и MVC Framework набирает его.
Наконец, Вопрос
Что мне не хватает, и как я могу получить MVC Framework, чтобы быть в курсе моего контроллера?
И, в этот момент, если вы все еще читаете это, спасибо. :)
1. Выполняется ли VS с использованием Cassini? Попробуйте изменить его на IIS Express и проверьте, продолжает ли он работать правильно. 2. Попробуйте установить [RouteDebugger] (http://nuget.org/packages/routedebugger) - возможно, это может дать вам некоторые подсказки относительно правильности регистрации маршрутов в IIS – Pranav
Спасибо @Pranav, но он уже на IIS. Отладчик маршрута показывает, что маршруты работают. – MisterJames
Может ли это быть проблемой? http://stackoverflow.com/questions/14971895/using-precompiledmvcengine-findview-throws-invalidoperationexception-and-looks-f – Tengiz