Mir*_*rek 6 c# asp.net-core asp.net-core-2.2
在此处的文档中:https : //docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-2.2
运行时在以下路径中搜索视图:
Run Code Online (Sandbox Code Playgroud)/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}
如何在此处添加另一条路径?
我想将我的视图组件及其各自的控制器放在一个名为 components 的项目文件夹中。
/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}
Run Code Online (Sandbox Code Playgroud)
我的动机:
我发现我的视图组件有自己的 JS 和 CSS 文件。我将所有 JS 捆绑并最小化在一个中site.min.js,所有 CSS 捆绑并最小化在它们的site.min.css. JS 总是类似$(function() { ... }),而 CSS 总是以一种顺序无关紧要的方式编写,因此在不知道顺序的情况下捆绑所有内容不是问题。
其中一些视图组件具有 javascripts,可以更改它们在服务器上的状态,例如对控制器操作的 AJAX 调用,该操作返回一些 JSON 或整个视图组件的 HTML。
由于控制器只是一个 C# 类,它们可以位于任何文件夹中,但是将带有相关 AJAX 操作的控制器移动到“视图”文件夹中感觉很愚蠢。
最后,我想要一个像这样的“组件”(不是真正的“视图组件”):
/Components/{View Component Name}/{View Name}
Run Code Online (Sandbox Code Playgroud)
Mir*_*rek 10
因此,在深入研究 aspnetcore 存储库一个小时后,我发现该组件的搜索路径是硬编码的,然后与普通视图搜索路径相结合。
// {0} is the component name, {1} is the view name.
private const string ViewPathFormat = "Components/{0}/{1}";
Run Code Online (Sandbox Code Playgroud)
然后将此路径发送到视图引擎
result = viewEngine.FindView(viewContext, qualifiedViewName, isMainPage: false);
Run Code Online (Sandbox Code Playgroud)
然后视图引擎使用可配置的视图路径生成完整路径。
Views/Shared/Components/Cart/Default.cshtmlViews/Home/Components/Cart/Default.cshtmlAreas/Blog/Views/Shared/Components/Cart/Default.cshtml如果你想把你的视图组件放到我想要的名为“Components”的根文件夹中,你可以做这样的事情。
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);
});
Run Code Online (Sandbox Code Playgroud)
在我看来这有点丑陋。但它有效。
您也可以像这样编写自己的扩展器。
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) {}
}
}
Run Code Online (Sandbox Code Playgroud)
在 Startup.cs 中
services.Configure<RazorViewEngineOptions>(o =>
{
o.ViewLocationExpanders.Add(new ComponentViewLocationExpander());
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4111 次 |
| 最近记录: |