ASP.NET Core MVC视图组件搜索路径 [英] ASP.NET Core MVC View Component search path

查看:111
本文介绍了ASP.NET Core MVC视图组件搜索路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此处的文档中: 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆