Asp.net MVC VirtualPathProvider отображает ошибку разбора - PullRequest
2 голосов
/ 18 августа 2010

Я работаю над системой плагинов для Asp.net MVC 2. У меня есть dll, содержащая контроллеры и представления в качестве встроенных ресурсов.

Я сканирую dll плагина для контроллера, используя StructureMap, и затем могу вытащить их и создать экземпляр по запросу. Это отлично работает. Затем у меня есть VirtualPathProvider, который я адаптировал из этого поста

public class AssemblyResourceProvider : VirtualPathProvider
{
    protected virtual string WidgetDirectory
    {
        get 
        { 
            return "~/bin";
        }
    }

    private bool IsAppResourcePath(string virtualPath)
    {
        var checkPath = VirtualPathUtility.ToAppRelative(virtualPath);
        return checkPath.StartsWith(WidgetDirectory, StringComparison.InvariantCultureIgnoreCase);
    }

    public override bool FileExists(string virtualPath)
    {
        return (IsAppResourcePath(virtualPath) || base.FileExists(virtualPath));
    }

    public override VirtualFile GetFile(string virtualPath)
    {
        return IsAppResourcePath(virtualPath) ? new AssemblyResourceVirtualFile(virtualPath) : base.GetFile(virtualPath);
    }

    public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies,
                                                       DateTime utcStart)
    {
        return IsAppResourcePath(virtualPath) ? null : base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
    }
}

internal class AssemblyResourceVirtualFile : VirtualFile
{
    private readonly string path;

    public AssemblyResourceVirtualFile(string virtualPath)
        : base(virtualPath)
    {
        path = VirtualPathUtility.ToAppRelative(virtualPath);
    }

    public override Stream Open()
    {
        var parts = path.Split('/');
        var resourceName = Path.GetFileName(path);

        var apath = HttpContext.Current.Server.MapPath(Path.GetDirectoryName(path));
        var assembly = Assembly.LoadFile(apath);
        return assembly != null ? assembly.GetManifestResourceStream(assembly.GetManifestResourceNames().SingleOrDefault(s => string.Compare(s, resourceName, true) == 0)) : null;
    }
}

Кажется, что VPP тоже работает нормально. Вид найден и вытащен в поток. Затем я получаю ошибку разбора Could not load type 'System.Web.Mvc.ViewUserControl<dynamic>'., которую я не могу найти ни в одном из предыдущих примеров подключаемых представлений. Почему моя точка зрения не компилируется на этом этапе?

Спасибо за любую помощь,

Ian

EDIT:

Становится ближе к ответу, но не совсем понятно, почему вещи не компилируются. Основываясь на комментариях, я проверил версии и все в V2, я думаю, что динамическая была введена в V2, так что это нормально. У меня даже не установлен V3, так что этого не может быть. Однако у меня есть представление для рендеринга, если я вообще уберу <dynamic>.

Таким образом, VPP работает, но только если представление не является строго типизированным или динамическим

Это имеет смысл для сценария со строгой типизацией, поскольку тип находится в динамически загружаемой dll, поэтому viewengine не будет знать об этом, даже если dll находится в корзине. Есть ли способ загрузки типов при запуске приложения? Рассматривая вариант с MEF вместо моего заказного решения Structuremap. Что ты думаешь?

Ответы [ 3 ]

2 голосов
/ 01 января 2011

Настройки, позволяющие анализировать строго типизированные представления, находятся в ~ / Views / Web.Config.Когда механизм просмотра использует провайдера виртуального пути, он не находится в папке представлений, поэтому не загружает эти настройки.

Если вы копируете все содержимое в узле страниц Views / Web.Config в корневой веб-каталог.Config, строго типизированные представления будут проанализированы правильно.

1 голос
/ 17 января 2011

Попробуйте добавить содержимое Views / Web.config непосредственно в основной файл web.config в определенном месте, например, для обработки виртуальных путей, например ~ / page / xxx.Подробности здесь: http://blog.sergkazakov.com/2011/01/aspnet-strongly-typed-view-and-virtual.html

0 голосов
/ 07 сентября 2015

Есть ли способ загрузки типов при запуске приложения?

Да, вы можете использовать BuildManager.AddReferencedAssembly (сборка) , где assembly - этоодин, содержащий запрошенный тип.Итак, как только вы используете MEF, последнее должно быть простым, но будьте осторожны, все должно быть сделано до Application_Start, поэтому вы можете использовать PreApplicationStartMethodAttribute .

...