Как включить контроллеры и представления из внешнего проекта в MVC6?



У меня есть несколько модулей, которые имеют контроллеры и представления. Это в основном расширение для моего веб-приложения. Каждый модуль находится в библиотеке классов.



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





Моя структура файлов решений выглядит следующим образом:



src
|
|-- Web.Common (Class Library Project)
| |- Files like: filters, my own controller etc...
|
|-- WebApplication (ASP.NET5 WebSite)
| |- wwwroot
| |- Controllers
| |- Views
| |- etc...
|
|-- Module 1 (Class Library Project)
| |- Controllers
| |- Views
|
|-- Module 2 etc...


Вот что я попробовал:





Я попытался реализовать свой собственный IViewLocationExpander



public class CustomViewLocationExpander : IViewLocationExpander
{
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
yield return "/../Module1.Web/Views/Home/TestView.cshtml";
yield return "../Module1.Web/Views/Home/TestView.cshtml";
yield return "/Module1.Web/Views/Home/TestView.cshtml";
yield return "~/../Module1.Web/Views/Home/TestView.cshtml";
}

public void PopulateValues(ViewLocationExpanderContext context)
{

}
}


Я перепробовал все пути, которые приходили мне в голову, но безуспешно : (



I получить:




Исключение InvalidOperationException: представление 'TestView' не найдено. Были проведены поиски в следующих местах:



~ / Module1.Web / Views / Home / TestView.cshtml
~/../ Module1.Web / Views / Home / TestView.cshtml
/ Module1.Web / Views / Home / TestView.cshtml
/../ Module1.Web / Views / Home / TestView.cshtml






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



Но здесь у меня тоже не было никакого успеха.





Может быть, есть функция для достижения этого, вызывая некоторые ASP.NET методы, но я этого не знаю.



Есть предположения?

521   3  

3 ответов:

Контроллеры будут загружаться автоматически. Чтобы загрузить представления, вам понадобятся EmbeddedFileProvider и CompositeFileProvider, оба из которых являются новыми, поэтому вам нужно будет получить их из ленты aspnetvnext.

Ссылайтесь на них в вашем стартовом проекте MVC6 project.json:

"Microsoft.AspNet.FileProviders.Composite": "1.0.0-*",
"Microsoft.AspNet.FileProviders.Embedded": "1.0.0-*",

Обновите регистрацию сервиса в Startup.cs:

    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.FileProvider = new CompositeFileProvider(
            new EmbeddedFileProvider(
                typeof(BooksController).GetTypeInfo().Assembly,
                "BookStore.Portal" // your external assembly's base namespace
            ),
            options.FileProvider
        );
    });

В project.json вашей внешней сборки добавьте следующее:

  "resource": "Views/**"

Вот пример реализации, который вы можете клонировать и запустить, чтобы увидеть его в действие: https://github.com/johnnyoshika/mvc6-view-components

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

Насколько я понимаю, в beta7 мы сможем упаковывать представления и другие файлы содержимого в библиотеку классов nuget, которая создается при построении библиотеки классов с помощью VS 2015. Но я понимаю, что когда основное веб-приложение добавляет зависимость от такого nuget, файлы содержимого будут добавлены в основное веб-приложение, т. е. мои представления будут добавлены ниже Views/MyModule или что-то в этом роде, чтобы их можно было использовать из основного веб-приложения.

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

Я думаю, что другой вариант-предварительно скомпилировать представления таким образом, чтобы они не существовали на диске как.файлы cshtml, но это сделает его более трудным для других, чтобы настроить представления.

Я достиг этого с помощью IViewLocationExpander и PhysicalFileProvider

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

public class MultiAssemblyViewLocationExpander : IViewLocationExpander
{
    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
    {
        var actionContext = (ResultExecutingContext)context.ActionContext;
        var assembly = actionContext.Controller.GetType().Assembly;
        var assemblyName = assembly.GetName().Name;

        foreach (var viewLocation in viewLocations)
            yield return "/" + assemblyName + viewLocation;
    }

    public void PopulateValues(ViewLocationExpanderContext context)
    {

    }
}

И в ConfigureServices методе:

services.Configure<RazorViewEngineOptions>(options =>
{
    options.FileProvider = new PhysicalFileProvider(HostingEnvironment.WebRootPath + "..\\..\\");
    options.ViewLocationExpanders.Add(new MultiAssemblyViewLocationExpander ());
});
PS: Я не тестировал это на опубликованном приложении. Но это будет легко исправить, если возникнут некоторые проблемы пути;)

Comments

    Ничего не найдено.