簡體   English   中英

ASP.NET Core MVC視圖組件搜索路徑

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM