簡體   English   中英

如何將外部項目中的控制器和視圖包含到MVC6中?

[英]How to include controllers and views from an external project into MVC6?

我有一些模塊,有控制器和視圖。 它基本上是我的Web應用程序的擴展。 每個模塊都在一個類庫中。

我想從我的Web應用程序加載這些程序集。 但我在這里沒有運氣。


我的解決方案文件結構如下:

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)
    {

    }
}

我嘗試了各種各樣的路徑,但我沒有運氣:(

我明白了:

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看起來不在WebApp的根路徑之外,並決定嘗試實現我自己的IFileProvider。

但在這里我也沒有任何成功。


也許有一個功能是通過調用一些ASP.NET方法來實現這一點,但我不知道。

有什么建議?

控制器將自動加載。 要加載視圖,您將需要EmbeddedFileProviderCompositeFileProvider ,這兩者都是新的,因此您需要從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

我認為除非您想使用某些非標准的第三方解決方案,否則視圖必須存在於主Web應用程序

我的理解是,在beta7中,我們將能夠將視圖和其他內容文件打包到我們使用VS 2015構建類庫時創建的類庫nuget中。但我的理解是,當主Web應用程序添加依賴於此類一個nuget,內容文件將被添加到主Web應用程序,即我的視圖將添加到Views / MyModule或類似的東西下面,以便它們可以從主Web應用程序中使用。

至少這是我希望采取的方法,以便其他人可以稍后閱讀和/或修改我的觀點。

我認為另一種選擇是預編譯視圖,使它們不像磁盤上的.cshtml文件那樣存在,但這會使其他人更難以自定義視圖。

我通過使用IViewLocationExpanderPhysicalFileProvider實現了這一點

我使用剃刀引擎的IFileProvider來設置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:我沒有在已發布的應用程序上對此進行測試。 但是如果出現一些路徑問題,很容易修復它;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM