如何将来自外部项目的控制器和视图包含到 MVC6 中?
How to include controllers and views from an external project into MVC6?
我有一些模块有控制器和视图。它基本上是我的网络应用程序的扩展。每个模块都在 class 库中。
我想从我的 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: The view 'TestView' was not found. The following locations were searched:
~/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 方法来实现,但我不知道。
有什么建议吗?
我认为视图必须存在于主 Web 应用程序中 unless you want to use some non-standard 3rd party solutions
我的理解是,在 beta7 中,我们将能够在使用 VS 2015 构建 class 库时创建的 class 库 nuget 中打包视图和其他内容文件。但是我的理解是当主网络应用程序添加对这样一个 nuget 的依赖时,内容文件将被添加到主网络应用程序,即我的视图将被添加到 Views/MyModule 或类似的东西下面,以便它们可以从主要网络应用程序。
至少这是我希望采取的方法,这样我的观点就可以被其他人阅读and/or 修改。
我认为另一种选择是预编译视图,使它们不作为 .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:我没有在已发布的应用程序上对此进行测试。但如果出现一些路径问题,修复它会很容易;)
控制器将自动加载。要加载视图,您需要 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
我有一些模块有控制器和视图。它基本上是我的网络应用程序的扩展。每个模块都在 class 库中。
我想从我的 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: The view 'TestView' was not found. The following locations were searched:
~/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 方法来实现,但我不知道。
有什么建议吗?
我认为视图必须存在于主 Web 应用程序中 unless you want to use some non-standard 3rd party solutions
我的理解是,在 beta7 中,我们将能够在使用 VS 2015 构建 class 库时创建的 class 库 nuget 中打包视图和其他内容文件。但是我的理解是当主网络应用程序添加对这样一个 nuget 的依赖时,内容文件将被添加到主网络应用程序,即我的视图将被添加到 Views/MyModule 或类似的东西下面,以便它们可以从主要网络应用程序。
至少这是我希望采取的方法,这样我的观点就可以被其他人阅读and/or 修改。
我认为另一种选择是预编译视图,使它们不作为 .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:我没有在已发布的应用程序上对此进行测试。但如果出现一些路径问题,修复它会很容易;)
控制器将自动加载。要加载视图,您需要 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