【问题标题】:ASP.NET Core MVC View Component search pathASP.NET Core MVC 查看组件搜索路径
【发布时间】:2019-09-07 07:45:34
【问题描述】:

在此处的文档中: https://docs.microsoft.com/en-us/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 的项目文件夹中。

/Components/{View Component Name}/{View Name}

我的动机:

我发现我的视图组件有自己的 JS 和 CSS 文件。我将所有 JS 捆绑并最小化在一个 site.min.js 中,并将所有 CSS 捆绑并最小化在它们的 site.min.css 中。 JS 总是类似于$(function() { ... }),而 CSS 总是以一种顺序无关紧要的方式编写,因此在不知道顺序的情况下捆绑所有内容不是问题。

其中一些视图组件有 javascripts 可以改变它们在服务器上的状态,例如对控制器操作的 AJAX 调用,该操作返回一些 JSON 或整个视图组件的 HTML。

由于控制器只是一个 C# 类,它们可以位于任何文件夹中,但将具有相关 AJAX 操作的控制器移动到“Views”文件夹感觉很愚蠢。

最后我想要一个像这样的“组件”(不是真正的“视图组件”):

/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

【问题讨论】:

    标签: c# asp.net-core asp.net-core-2.2


    【解决方案1】:

    您可以向RazorViewEngineOptions 添加其他查看位置格式。例如,要添加满足您要求的路径,您可以使用以下内容:

    services
        .AddMvc()
        .AddRazorOptions(o =>
        {
            // /Components/{View Component Name}/{View Name}.cshtml
            o.ViewLocationFormats.Add("/{0}.cshtml");
            o.PageViewLocationFormats.Add("/{0}.cshtml");
        });
    

    如上所示,views(使用控制器和操作时)和 页面视图(使用 Razor 页面时)有不同的属性。还有一个区域属性,但我在此示例中将其省略以使其略短。

    这种方法的缺点是视图位置格式不能应用于视图组件。例如,当在Home 中查找Index 视图时,Razor 现在还将查找位于项目根目录的Index.cshtml。这可能没问题,因为它是最后搜索的位置,我希望您不会有任何视图位于项目的根部,但这当然值得关注。

    【讨论】:

      【解决方案2】:

      于是在aspnetcore仓库挖了一个小时后,发现组件的搜索路径是hardcoded,然后结合普通视图搜索路径。

      // {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/<strong>Components/Cart/Default</strong>.cshtml
      • Views/Home/<strong>Components/Cart/Default</strong>.cshtml
      • Areas/Blog/Views/Shared/<strong>Components/Cart/Default</strong>.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());   
      });
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-05
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 2018-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多