[英]ASP.NET Core MVC View Component search path
在此處的文檔中: https : //docs.microsoft.com/zh-cn/aspnet/core/mvc/views/view-components?view=aspnetcore-2.2
運行時在以下路徑中搜索視圖:
/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”的項目文件夾中將View組件及其各自的控制器包含在其中。
/Components/{View Component Name}/{View Name}
我的動力:
我發現我的視圖組件具有自己的JS和CSS文件。 我將所有JS捆綁和最小化在一個site.min.js
並將所有CSS捆綁和最小化在其site.min.css
。 JS總是像$(function() { ... })
,而CSS總是以順序無關緊要的方式編寫,因此在不知道順序的情況下捆綁所有對象就不是問題。
這些視圖組件中的某些組件具有javascript,這些javascript可更改其在服務器上的狀態,例如對控制器操作的AJAX調用,該操作返回一些JSON或整個視圖組件的HTML。
由於控制器只是C#類,因此它們可以位於任何文件夾中,但是將具有相關AJAX操作的控制器移動到“視圖”文件夾中感覺很愚蠢。
最后,我希望有一個像這樣的“組件”(不是真正的“視圖組件”):
/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存儲庫后,我發現該組件的搜索路徑是經過硬編碼的 ,然后與常規視圖搜索路徑結合在一起。
// {0} is the component name, {1} is the view name.
private const string ViewPathFormat = "Components/{0}/{1}";
然后將此路徑發送到視圖引擎
result = viewEngine.FindView(viewContext, qualifiedViewName, isMainPage: false);
然后,視圖引擎使用可配置的視圖路徑生成完整路徑。
Views/Shared/ Components/Cart/Default .cshtml
Views/Home/ Components/Cart/Default .cshtml
Areas/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);
});
我認為這有點丑陋。 但這有效。
您也可以這樣編寫自己的擴展器。
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中
services.Configure<RazorViewEngineOptions>(o =>
{
o.ViewLocationExpanders.Add(new ComponentViewLocationExpander());
});
您可以向RazorViewEngineOptions
添加其他視圖位置格式 。 例如,要添加一條滿足您要求的路徑,可以使用以下方法:
services
.AddMvc()
.AddRazorOptions(o =>
{
// /Components/{View Component Name}/{View Name}.cshtml
o.ViewLocationFormats.Add("/{0}.cshtml");
o.PageViewLocationFormats.Add("/{0}.cshtml");
});
如上所示, 視圖 (使用控制器和動作時)和頁面視圖 (使用剃刀頁面)時具有不同的屬性。 還有一個區域屬性,但在此示例中我將其省略,以使其略短一些。
這樣做的缺點的方法是,觀察位置格式不僅適用於視圖組件。 例如,當在Home
內查找Index
視圖時,Razor現在還將在項目的根目錄下查找Index.cshtml
。 這可能很好,因為它是最后搜索的位置,並且我希望您在項目的根目錄不會有任何視圖,但這當然值得一提。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.