Представление 'Index' не было найдено из плагина - PullRequest
0 голосов
/ 28 марта 2020

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

Это прекрасно работает, но при выполнении области выдает следующую ошибку:

Произошло необработанное исключение при обработке запроса.

InvalidOperationException: представление «Индекс» не найдено. Были найдены следующие местоположения: /Views/TestHome/Index.cshtml /Views/Shared/Index.cshtml /Pages/Shared/Index.cshtml

Площадь in называется TestArea, но не отображает область моего плагина.

Структура моего плагина следующая:

enter image description here

Структура моего основного проекта следующая:

enter image description here

В папке Области / Расширения / TestArea I поместите сборки и в папку Areas / TestArea , которую я поместил представления.

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

Я использую следующий код:

PluginExtensions.cs

public static class PluginExtensions
{

    public static IMvcBuilder AddExtensions(this IMvcBuilder mvc)
    {
        List<string> extensionAssemblies = new List<string>();
        var serviceProvider = mvc.Services.BuildServiceProvider();
        var configuration = serviceProvider.GetService<IConfiguration>();
        var hostingEnvironment = serviceProvider.GetService<IWebHostEnvironment>();
        var logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<Startup>();
        List<string> extensionDirectories = EnumerateExtensionDirectories(serviceProvider).ToList();
        List<string> searchPatternList = new List<string>
        {
            "*Extension.Mvc.dll"
        };
        mvc.ConfigureApplicationPartManager(apm =>
        {
            foreach(var extensionDirectory in extensionDirectories)
            {
                for (int i = 0; i < searchPatternList.Count; i++)
                {
                    List<string> tempList = EnumerateExtensionAssemblies(extensionDirectory, searchPatternList[i]).ToList();
                    if (tempList != null && tempList.Count > 0)
                        extensionAssemblies.AddRange(tempList);
                }//for(int i=0;i< searchPatternList.Count; i++)
                foreach (var extensionPath in extensionAssemblies)
                {
                    var pluginAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(extensionPath);
                    var partFactory = ApplicationPartFactory.GetApplicationPartFactory(pluginAssembly);

                    foreach (var part in partFactory.GetApplicationParts(pluginAssembly))
                    {
                        apm.ApplicationParts.Add(part);
                    }

                    var relatedAssemblies = RelatedAssemblyAttribute.GetRelatedAssemblies(pluginAssembly, throwOnError: true);
                    foreach (var assembly in relatedAssemblies)
                    {
                        if (assembly.FullName.ToLower().IndexOf("extension.mvc.views") >= 0)
                        {
                            **var compiledRazorAssemblyApplicationParts = new CompiledRazorAssemblyApplicationPartFactory().GetApplicationParts(AssemblyLoadContext.Default.LoadFromAssemblyPath(assembly.Location));**
                            foreach (var craapf in compiledRazorAssemblyApplicationParts)
                                apm.ApplicationParts.Add(craapf);
                        }
                        else
                        {
                            partFactory = ApplicationPartFactory.GetApplicationPartFactory(assembly);
                            foreach (var part in partFactory.GetApplicationParts(assembly))
                            {
                                apm.ApplicationParts.Add(part);
                            }
                        }

                    }
                }


            }
        });
        return mvc;
    }}

Startup.cs

  public void ConfigureServices(IServiceCollection services)
    {
        services.AddSession(options =>
        {
            options.Cookie.Name = ".Matios.Session";
            options.IdleTimeout = TimeSpan.FromMinutes(30);
            options.Cookie.IsEssential = true;
        });
        services.AddControllersWithViews();
        services.AddResponseCaching();
        services.AddRazorPages();
        services.AddAntiforgery(options =>
        {
            options.Cookie.Name = ".Matios.Antiforgery";
        });
        var iMvc= services.AddMvc(options =>
        {
            options.Filters.Add(new SessionExpireAttribute());

            options.EnableEndpointRouting = true;
        })**.AddExtensions()**;
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }

Наконец, URL, который я выполняю, следующий: http://localhost: 5000 / TestArea / TestHome / Index

Можете ли вы мне помочь?

1 Ответ

0 голосов
/ 28 марта 2020

Мне удалось решить проблему, выполнив следующие действия:

Первый подключаемый модуль: Я создал полностью работающий MVC веб-сайт с нужной мне областью. В этом случае просто ванильный веб-сайт украшал HomeController:

    [Area("TestArea")]
    public class HomeController : Controller

Затем перемещал «материал» под TestArea следующим образом:

enter image description here

Второе преобразование в DLL: Преобразование подключаемого модуля в библиотеку классов, например:

enter image description here

Третий Хозяин: Я создал веб-сайт VANILLA без областей. Добавил «Подключаемые сборки», как вы сделали, НО, я добавил их в ROOT проекта ..... Вот так:

enter image description here

Поддержка четвертой области: В ОБА проекты я добавил поддержку маршрутизации для областей в класс запуска следующим образом:

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if(env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {//this was added to both projects
                endpoints.MapControllerRoute(
                    name: "areaDefault",
                    pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }

Пятое Изменено PluginExtensions: Изменен класс PluginExtensions, который вы должны выглядеть в текущем каталоге следующим образом:

var extensionDirectories = new List<string> { Directory.GetCurrentDirectory() };

Наконец Я не добавляю «Представления» к проекту хоста ... Потому что они должны быть скомпилированы в DLL для плагина .... На самом деле я даже не сделал добавить папку областей ... так как каждый «плагин области» должен контролировать свою собственную «область».

Вот результат: Обратите внимание, как URL-адрес области, которая НЕ существует в текущий сайт ... Он был загружен динамически! Ура! enter image description here

...