如何将外部项目中的控制器和视图包含到MVC6中
本文关键字:视图 包含 MVC6 控制器 外部 项目 | 更新日期: 2023-09-27 18:04:04
我有一些模块有控制器和视图。它基本上是我的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/视图/Home/TestView.cshtml~/. ./Module1.Web/视图/Home/TestView.cshtml/Module1.Web/视图/Home/TestView.cshtml/. ./Module1.Web/视图/Home/TestView.cshtml
所以我想也许默认的IFileProvider不会在WebApp的根路径外看,并决定尝试实现我自己的IFileProvider。
但是在这里我也没有成功。
也许有一个特性可以通过调用一些ASP来实现这一点。. NET方法,但我不知道。
显示吗?
控制器将自动加载。要加载视图,您将需要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
我认为视图必须存在于主web应用程序中,除非你想使用一些非标准的第三方解决方案
我的理解是,在beta7中,我们将能够将视图和其他内容文件打包到类库nuget中,该nuget是在VS 2015中构建类库时创建的。但我的理解是,当主web应用程序添加依赖于这样的nuget时,内容文件将被添加到主web应用程序,即我的视图将被添加到views/MyModule或类似的东西下,以便它们可以从主web应用程序中使用。
至少这是我期望采取的方法,这样我的视图以后可以被其他人读取和/或修改。
我认为另一种选择是预编译视图,这样它们就不会以。cshtml文件的形式存在于磁盘上,但这会使其他人更难以自定义视图。
我通过使用IViewLocationExpander
和PhysicalFileProvider
实现了这一点
我使用剃刀引擎的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:我没有在已发布的应用程序上进行测试。但是如果出现一些路径问题就很容易修复了;)