如何将外部项目中的控制器和视图包含到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 ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable 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。

但在这里我也没有任何成功。


也许有一个function是通过调用一些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(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 ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable 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(options => { options.FileProvider = new PhysicalFileProvider(HostingEnvironment.WebRootPath + "..\\..\\"); options.ViewLocationExpanders.Add(new MultiAssemblyViewLocationExpander ()); }); 

PS:我没有在已发布的应用程序上测试它。 但是如果出现一些路径问题,很容易解决它;)