我有一些有控制器和视图的模块。它基本上是我的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 /查看/主页/ TestView.cshtml 〜/../ Module1.Web /浏览/首页/ TestView.cshtml /Module1.Web/Views/Home/TestView.cshtml /../ Module1.Web /查看/主页/ TestView.cshtml
所以我想也许默认的IFileProvider看起来不在WebApp的根路径之外,并决定尝试实现我自己的IFileProvider。
但在这里我也没有任何成功。
也许有一个功能可以通过调用一些ASP.NET方法来实现这一点,但我不知道。
有什么建议吗?
答案 0 :(得分:8)
控制器将自动加载。要加载视图,您需要EmbeddedFileProvider
和CompositeFileProvider
,这两者都是新视图,因此您需要从aspnetvnext
Feed中获取视图。
在启动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
答案 1 :(得分:2)
我认为观看次数必须存在于主要网络应用4018
中我的理解是,在beta7中,我们将能够将视图和其他内容文件打包到我们使用VS 2015构建类库时创建的类库nuget中。但我的理解是,当主Web应用程序添加了依赖于这样的nuget,内容文件将被添加到主Web应用程序中,即我的视图将添加到Views / MyModule之下或类似的东西,以便它们可以从主Web应用程序中使用。
至少这是我希望采取的方法,以便其他人可以稍后阅读和/或修改我的观点。
我认为另一个选择是预先编译视图,使它们不像磁盘上那样存在于.cshtml文件中,但这会让其他人更难以自定义视图。
答案 2 :(得分:2)
我使用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:我没有在已发布的应用程序上对此进行测试。但如果出现一些路径问题,很容易解决它;)