ASP.NET Core MVC视图组件搜索路径 [英] ASP.NET Core MVC View Component search path
问题描述
在此处的文档中: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view = aspnetcore-2.2
运行时在以下路径中搜索视图:
The runtime searches for the view in the following paths:
/Views/{Controller Name}/Components/{View Component Name}/{View Name}
/Views/Shared/Components/{View Component Name}/{View Name}
/Pages/Shared/Components/{View Component Name}/{View Name}
如何在此处添加其他路径?
How can I add another path here?
我想在一个名为"components"的项目文件夹中将其视图组件及其各自的控制器放在其中.
I'd like to have my view components with their respective controllers in one project folder named components like this.
/Components/{View Component Name}/{View Name}
我的动力:
My motivation:
我发现我的视图组件具有自己的JS和CSS文件.我将所有JS捆绑和最小化在一个 site.min.js
中,并将所有CSS捆绑和最小化在它们的 site.min.css
中.JS总是像 $(function(){...})
之类的东西,而CSS总是以顺序无关紧要的方式编写,因此在不知道顺序的情况下将所有对象捆绑在一起是没有问题的.
I find out my view components have their own JS and CSS files. I have all JS bundled and minimized in one site.min.js
and all CSS bundled and minimized in their site.min.css
. The JS are always something like $(function() { ... })
and the CSS are always written in a way that order does not matter so bundling all without knowing the order is not a problem.
其中一些视图组件具有javascript,这些javascript会更改其在服务器上的状态,例如AJAX调用控制器的操作,该操作返回一些JSON或整个视图组件的HTML.
Some of those view components have javascripts which change their state on server e.g. AJAX call to a controller's action which returns some JSON or the whole view component's HTML.
由于控制器只是C#类,因此它们可以位于任何文件夹中,但是将具有相关AJAX动作的控制器移动到视图"文件夹中感觉很愚蠢.
Since Controllers are just a C# classes they can be in any folder but it feels stupid to move the controller with the relevant AJAX action to the "Views" folder.
最后,我想拥有一个像这样的组件"(不是真正的视图组件"):
In the end I'd like to have a "component" (not really a "view component" only) like this:
/Components/SomeViewComponent/Default.cshtml
/Components/SomeViewComponent/SomeViewComponentController.cs
/Components/SomeViewComponent/SomeViewComponent.cs
/Components/SomeViewComponent/SomeViewComponent.css
/Components/SomeViewComponent/SomeViewComponent.js
/Components/SomeViewComponent/SomeViewComponent.en.resx
/Components/SomeViewComponent/SomeViewComponent.cs-CZ.resx
推荐答案
因此,在一个小时内深入aspnetcore存储库后,我发现该组件的搜索路径为
So after an hour digging into the aspnetcore repository, I found the component's search path is hardcoded and then combined with normal view search paths.
// {0} is the component name, {1} is the view name.
private const string ViewPathFormat = "Components/{0}/{1}";
然后将此路径发送到视图引擎
This path is then sent into the view engine
result = viewEngine.FindView(viewContext, qualifiedViewName, isMainPage: false);
然后,视图引擎使用可配置的视图路径生成完整路径.
The view engine then produces the full path, using the configurable view paths.
-
视图/共享/组件/购物车/默认 .cshtml
-
视图/主页/组件/购物车/默认 .cshtml
-
区域/博客/视图/共享/组件/购物车/默认 .cshtml
Views/Shared/Components/Cart/Default.cshtml
Views/Home/Components/Cart/Default.cshtml
Areas/Blog/Views/Shared/Components/Cart/Default.cshtml
如果要根据需要将视图组件放置到名为"Components"的根文件夹中,则可以执行以下操作.
If you want to place your view components into a root folder named "Components" as I wanted, you can do something like this.
services.Configure<RazorViewEngineOptions>(o =>
{
// {2} is area, {1} is controller,{0} is the action
// the component's path "Components/{ViewComponentName}/{ViewComponentViewName}" is in the action {0}
o.ViewLocationFormats.Add("/{0}" + RazorViewEngine.ViewExtension);
});
在我看来,这有点丑陋.但这有效.
That's kind of ugly in my opinion. But it works.
您也可以这样编写自己的扩展器.
You can also write your own expander like this.
namespace TestMvc
{
using Microsoft.AspNetCore.Mvc.Razor;
using System.Collections.Generic;
public class ComponentViewLocationExpander : IViewLocationExpander
{
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
{
// this also feels ugly
// I could not find another way to detect
// whether the view name is related to a component
// but it's somewhat better than adding the path globally
if (context.ViewName.StartsWith("Components"))
return new string[] { "/{0}" + RazorViewEngine.ViewExtension };
return viewLocations;
}
public void PopulateValues(ViewLocationExpanderContext context) {}
}
}
在Startup.cs中
And in Startup.cs
services.Configure<RazorViewEngineOptions>(o =>
{
o.ViewLocationExpanders.Add(new ComponentViewLocationExpander());
});
这篇关于ASP.NET Core MVC视图组件搜索路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!