ASP.NET Core 中的视图组件View components in ASP.NET Core

作者:Rick AndersonBy Rick Anderson

查看或下载示例代码如何下载View or download sample code (how to download)

视图组件View components

视图组件与分部视图类似,但它们的功能更加强大。View components are similar to partial views, but they're much more powerful. 视图组件不使用模型绑定,并且仅依赖调用时提供的数据。View components don't use model binding, and only depend on the data provided when calling into it. 本文是使用控制器和视图编写的,但视图组件也适用于 Razor 页。This article was written using controllers and views, but view components also work with Razor Pages.

视图组件:A view component:

  • 呈现一个区块而不是整个响应。Renders a chunk rather than a whole response.
  • 包括控制器和视图间发现的相同关注点分离和可测试性优势。Includes the same separation-of-concerns and testability benefits found between a controller and view.
  • 可以有参数和业务逻辑。Can have parameters and business logic.
  • 通常从布局页调用。Is typically invoked from a layout page.

视图组件可用于具有可重用呈现逻辑(对分部视图来说过于复杂)的任何位置,例如:View components are intended anywhere you have reusable rendering logic that's too complex for a partial view, such as:

  • 动态导航菜单Dynamic navigation menus
  • 标记云(查询数据库的位置)Tag cloud (where it queries the database)
  • 登录面板Login panel
  • 购物车Shopping cart
  • 最近发布的文章Recently published articles
  • 典型博客上的边栏内容Sidebar content on a typical blog
  • 一个登录面板,呈现在每页上并显示注销或登录链接,具体取决于用户的登录状态A login panel that would be rendered on every page and show either the links to log out or log in, depending on the log in state of the user

视图组件由两部分组成:类(通常派生自 ViewComponent)及其返回的结果(通常为视图)。A view component consists of two parts: the class (typically derived from ViewComponent) and the result it returns (typically a view). 与控制器一样,视图组件也可以是 POCO,但大多数开发人员都希望利用派生自 ViewComponent 的可用方法和属性。Like controllers, a view component can be a POCO, but most developers will want to take advantage of the methods and properties available by deriving from ViewComponent.

考虑视图组件是否满足应用的规范时,请考虑 Razor 改用组件。When considering if view components meet an app's specifications, consider using Razor components instead. Razor 组件还将标记与 c # 代码结合起来,以生成可重用的 UI 单元。Razor components also combine markup with C# code to produce reusable UI units. Razor 在提供客户端 UI 逻辑和组合时,组件旨在提高开发人员的工作效率。Razor components are designed for developer productivity when providing client-side UI logic and composition. 有关详细信息,请参阅 创建和使用 ASP.NET Core Razor 组件For more information, see 创建和使用 ASP.NET Core Razor 组件. 有关如何将 Razor 组件合并到 MVC 或 Razor 页面应用程序的信息,请参阅 预呈现和集成 ASP.NET Core Razor 组件For information on how to incorporate Razor components into an MVC or Razor Pages app, see 预呈现和集成 ASP.NET Core Razor 组件.

创建视图组件Creating a view component

本部分包含创建视图组件的高级别要求。This section contains the high-level requirements to create a view component. 本文后续部分将详细检查每个步骤并创建视图组件。Later in the article, we'll examine each step in detail and create a view component.

视图组件类The view component class

可通过以下任一方法创建视图组件类:A view component class can be created by any of the following:

  • 从 ViewComponent 派生Deriving from ViewComponent
  • 使用 [ViewComponent] 属性修饰类,或者从具有 [ViewComponent] 属性的类派生Decorating a class with the [ViewComponent] attribute, or deriving from a class with the [ViewComponent] attribute
  • 创建名称以 ViewComponent 后缀结尾的类Creating a class where the name ends with the suffix ViewComponent

与控制器一样,视图组件必须是公共、非嵌套和非抽象的类。Like controllers, view components must be public, non-nested, and non-abstract classes. 视图组件名称是删除了“ViewComponent”后缀的类名。The view component name is the class name with the "ViewComponent" suffix removed. 也可以使用 ViewComponentAttribute.Name 属性显式指定它。It can also be explicitly specified using the ViewComponentAttribute.Name property.

视图组件类:A view component class:

  • 完全支持构造函数依赖关系注入Fully supports constructor dependency injection

  • 不参与控制器生命周期,这意味着不能在视图组件中使用筛选器Doesn't take part in the controller lifecycle, which means you can't use filters in a view component

视图组件方法View component methods

视图组件以返回 Task<IViewComponentResult>InvokeAsync 方法,或是以返回 IViewComponentResult 的同步 Invoke 方法定义其逻辑。A view component defines its logic in an InvokeAsync method that returns a Task<IViewComponentResult> or in a synchronous Invoke method that returns an IViewComponentResult. 参数直接来自视图组件的调用,而不是来自模型绑定。Parameters come directly from invocation of the view component, not from model binding. 视图组件从不直接处理请求。A view component never directly handles a request. 通常,视图组件通过调用 View 方法来初始化模型并将其传递到视图。Typically, a view component initializes a model and passes it to a view by calling the View method. 总之,视图组件方法:In summary, view component methods:

  • 定义返回 Task<IViewComponentResult>InvokeAsync 方法,或是返回 IViewComponentResult 的同步 Invoke 方法。Define an InvokeAsync method that returns a Task<IViewComponentResult> or a synchronous Invoke method that returns an IViewComponentResult.
  • 通常通过调用方法来初始化模型并将其传递给视图 ViewComponent ViewTypically initializes a model and passes it to a view by calling the ViewComponent View method.
  • 参数来自调用方法,而不是 HTTP。Parameters come from the calling method, not HTTP. 没有模型绑定。There's no model binding.
  • 不可直接作为 HTTP 终结点进行访问。Are not reachable directly as an HTTP endpoint. 通过代码调用它们(通常在视图中)。They're invoked from your code (usually in a view). 视图组件从不处理请求。A view component never handles a request.
  • 在签名上重载,而不是当前 HTTP 请求的任何详细信息。Are overloaded on the signature rather than any details from the current HTTP request.

视图搜索路径View search path

运行时在以下路径中搜索视图:The runtime searches for the view in the following paths:

  • /Views/{Controller Name}/Components/{View Component Name}/{View Name}/Views/{Controller Name}/Components/{View Component Name}/{View Name}
  • /Views/Shared/Components/{View Component Name}/{View Name}/Views/Shared/Components/{View Component Name}/{View Name}
  • /Pages/Shared/Components/{View Component Name}/{View Name}/Pages/Shared/Components/{View Component Name}/{View Name}

搜索路径适用于使用控制器 + 视图和页的项目 Razor 。The search path applies to projects using controllers + views and Razor Pages.

视图组件的默认视图名称为“默认”,这意味着视图文件通常命名为“Default.cshtml”。The default view name for a view component is Default, which means your view file will typically be named Default.cshtml. 可以在创建视图组件结果或调用 View 方法时指定不同的视图名称。You can specify a different view name when creating the view component result or when calling the View method.

建议将视图文件命名为 Default.cshtml 并使用 Views/Shared/Components/{View Component Name}/{View Name} 路径。We recommend you name the view file Default.cshtml and use the Views/Shared/Components/{View Component Name}/{View Name} path. 此示例中使用的 PriorityList 视图组件对视图组件视图使用 Views/Shared/Components/PriorityList/Default.cshtml。The PriorityList view component used in this sample uses Views/Shared/Components/PriorityList/Default.cshtml for the view component view.

自定义视图搜索路径Customize the view search path

若要自定义视图搜索路径,请修改 Razor 的 ViewLocationFormats 集合。To customize the view search path, modify Razor's ViewLocationFormats collection. 例如,将新项添加到集合,以搜索路径“/Components/{视图组件名称}/{视图名称}”中的视图:For example, to search for views within the path "/Components/{View Component Name}/{View Name}", add a new item to the collection:

services.AddMvc()
    .AddRazorOptions(options =>
    {
        options.ViewLocationFormats.Add("/{0}.cshtml");
    })
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

在前面的代码中,占位符“{0}”表示路径“Components/{视图组件名称}/{视图名称}”。In the preceding code, the placeholder "{0}" represents the path "Components/{View Component Name}/{View Name}".

调用视图组件Invoking a view component

要使用视图组件,请在视图中调用以下内容:To use the view component, call the following inside a view:

@await Component.InvokeAsync("Name of view component", {Anonymous Type Containing Parameters})

参数将传递给 InvokeAsync 方法。The parameters will be passed to the InvokeAsync method. 本文中开发的 PriorityList 视图组件调用自 Views/ToDo/Index.cshtml 视图文件。The PriorityList view component developed in the article is invoked from the Views/ToDo/Index.cshtml view file. 在下例中,使用两个参数调用 InvokeAsync 方法:In the following, the InvokeAsync method is called with two parameters:

@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })

调用视图组件作为标记帮助程序Invoking a view component as a Tag Helper

对于 ASP.NET Core 1.1 及更高版本,可以调用视图组件作为标记帮助程序For ASP.NET Core 1.1 and higher, you can invoke a view component as a Tag Helper:

<vc:priority-list max-priority="2" is-done="false">
</vc:priority-list>

标记帮助程序采用 Pascal 大小写格式的类和方法参数将转换为各自相应的短横线格式Pascal-cased class and method parameters for Tag Helpers are translated into their kebab case. 要调用视图组件的标记帮助程序使用 <vc></vc> 元素。The Tag Helper to invoke a view component uses the <vc></vc> element. 按如下方式指定视图组件:The view component is specified as follows:

<vc:[view-component-name]
  parameter1="parameter1 value"
  parameter2="parameter2 value">
</vc:[view-component-name]>

若要将视图组件用作标记帮助程序,请使用 @addTagHelper 指令注册包含视图组件的程序集。To use a view component as a Tag Helper, register the assembly containing the view component using the @addTagHelper directive. 如果视图组件位于名为“MyWebApp”的程序集中,请将以下指令添加到 _ViewImports.cshtml 文件:If your view component is in an assembly called MyWebApp, add the following directive to the _ViewImports.cshtml file:

@addTagHelper *, MyWebApp

可将视图组件作为标记帮助程序注册到任何引用视图组件的文件。You can register a view component as a Tag Helper to any file that references the view component. 要详细了解如何注册标记帮助程序,请参阅管理标记帮助程序作用域See Managing Tag Helper Scope for more information on how to register Tag Helpers.

本教程中使用的 InvokeAsync 方法:The InvokeAsync method used in this tutorial:

@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })

在标记帮助程序标记中:In Tag Helper markup:

<vc:priority-list max-priority="2" is-done="false">
</vc:priority-list>

在以上示例中,PriorityList 视图组件变为 priority-listIn the sample above, the PriorityList view component becomes priority-list. 视图组件的参数作为短横线格式的属性进行传递。The parameters to the view component are passed as attributes in kebab case.

从控制器直接调用视图组件Invoking a view component directly from a controller

视图组件通常从视图调用,但你可以直接从控制器方法调用它们。View components are typically invoked from a view, but you can invoke them directly from a controller method. 尽管视图组件不定义控制器等终结点,但你可以轻松实现返回 ViewComponentResult 内容的控制器操作。While view components don't define endpoints like controllers, you can easily implement a controller action that returns the content of a ViewComponentResult.

在此示例中,视图组件直接从控制器调用:In this example, the view component is called directly from the controller:

public IActionResult IndexVC()
{
    return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}

演练:创建简单的视图组件Walkthrough: Creating a simple view component

下载、生成和测试起始代码。Download, build and test the starter code. 它是一个带有 ToDo 控制器的简单项目,该控制器显示 ToDo 项的列表。It's a simple project with a ToDo controller that displays a list of ToDo items.

ToDo 列表

添加 ViewComponent 类Add a ViewComponent class

创建一个 ViewComponents 文件夹并添加以下 PriorityListViewComponent 类:Create a ViewComponents folder and add the following PriorityListViewComponent class:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ViewComponentSample.Models;

namespace ViewComponentSample.ViewComponents
{
    public class PriorityListViewComponent : ViewComponent
    {
        private readonly ToDoContext db;

        public PriorityListViewComponent(ToDoContext context)
        {
            db = context;
        }

        public async Task<IViewComponentResult> InvokeAsync(
        int maxPriority, bool isDone)
        {
            var items = await GetItemsAsync(maxPriority, isDone);
            return View(items);
        }
        private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
        {
            return db.ToDo.Where(x => x.IsDone == isDone &&
                                 x.Priority <= maxPriority).ToListAsync();
        }
    }
}

代码说明:Notes on the code:

  • 视图组件类可以包含在项目的任意文件夹中。View component classes can be contained in any folder in the project.

  • 因为类名 PriorityListViewComponent 以后缀 ViewComponent 结尾,所以运行时将在从视图引用类组件时使用字符串“PriorityList”。Because the class name PriorityList ViewComponent ends with the suffix ViewComponent, the runtime will use the string "PriorityList" when referencing the class component from a view. 我稍后将进行详细解释。I'll explain that in more detail later.

  • [ViewComponent] 属性可以更改用于引用视图组件的名称。The [ViewComponent] attribute can change the name used to reference a view component. 例如,我们可以将类命名为 XYZ 并应用 ViewComponent 属性:For example, we could've named the class XYZ and applied the ViewComponent attribute:

    [ViewComponent(Name = "PriorityList")]
       public class XYZ : ViewComponent
    
  • 上面的 [ViewComponent] 属性通知视图组件选择器在查找与组件相关联的视图时使用名称 PriorityList,以及在从视图引用类组件时使用字符串“PriorityList”。The [ViewComponent] attribute above tells the view component selector to use the name PriorityList when looking for the views associated with the component, and to use the string "PriorityList" when referencing the class component from a view. 我稍后将进行详细解释。I'll explain that in more detail later.

  • 组件使用依赖关系注入以使数据上下文可用。The component uses dependency injection to make the data context available.

  • InvokeAsync 公开可以从视图调用的方法,且可以采用任意数量的参数。InvokeAsync exposes a method which can be called from a view, and it can take an arbitrary number of arguments.

  • InvokeAsync 方法返回满足 isDonemaxPriority 参数的 ToDo 项集。The InvokeAsync method returns the set of ToDo items that satisfy the isDone and maxPriority parameters.

创建视图组件 Razor 视图Create the view component Razor view

  • 创建 Views/Shared/Components 文件夹。Create the Views/Shared/Components folder. 此文件夹 必须 命名为 ComponentsThis folder must be named Components.

  • 创建 Views/Shared/Components/PriorityList 文件夹。Create the Views/Shared/Components/PriorityList folder. 此文件夹名称必须与视图组件类的名称或类名去掉后缀(如果遵照约定并在类名中使用了“ViewComponent”后缀)的名称相匹配。This folder name must match the name of the view component class, or the name of the class minus the suffix (if we followed convention and used the ViewComponent suffix in the class name). 如果使用了 ViewComponent 属性,则类名称需要匹配指定的属性。If you used the ViewComponent attribute, the class name would need to match the attribute designation.

  • 创建 Views/Shared/Components/PriorityList/Default ... Razor view:Create a Views/Shared/Components/PriorityList/Default.cshtml Razor view:

    @model IEnumerable<ViewComponentSample.Models.TodoItem>
    
    <h3>Priority Items</h3>
    <ul>
        @foreach (var todo in Model)
        {
            <li>@todo.Name</li>
        }
    </ul>
    

    Razor视图采用列表 TodoItem ,并显示它们。The Razor view takes a list of TodoItem and displays them. 如果视图组件 InvokeAsync 方法不传递视图名称(如示例中所示),则按照约定使用“默认”作为视图名称。If the view component InvokeAsync method doesn't pass the name of the view (as in our sample), Default is used for the view name by convention. 在本教程后面部分,我将演示如何传递视图名称。Later in the tutorial, I'll show you how to pass the name of the view. 要替代特定控制器的默认样式,请将视图添加到控制器特定的视图文件夹(例如 Views/ToDo/Components/PriorityList/Default.cshtml)。To override the default styling for a specific controller, add a view to the controller-specific view folder (for example Views/ToDo/Components/PriorityList/Default.cshtml).

    如果视图组件是控制器特定的,则可将其添加到控制器特定的文件夹 (Views/ToDo/Components/PriorityList/Default.cshtml)。If the view component is controller-specific, you can add it to the controller-specific folder (Views/ToDo/Components/PriorityList/Default.cshtml).

  • 将包含优先级列表组件调用的 div 添加到 Views/ToDo/index.cshtml 文件底部:Add a div containing a call to the priority list component to the bottom of the Views/ToDo/index.cshtml file:

    </table>
    <div>
        @await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
    </div>
    

标记 @await Component.InvokeAsync 显示调用视图组件的语法。The markup @await Component.InvokeAsync shows the syntax for calling view components. 第一个参数是要调用的组件的名称。The first argument is the name of the component we want to invoke or call. 后续参数将传递给该组件。Subsequent parameters are passed to the component. InvokeAsync 可以采用任意数量的参数。InvokeAsync can take an arbitrary number of arguments.

测试应用。Test the app. 下图显示 ToDo 列表和优先级项:The following image shows the ToDo list and the priority items:

Todo 列表和优先级项

也可直接从控制器调用视图组件:You can also call the view component directly from the controller:

public IActionResult IndexVC()
{
    return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}

IndexVC 操作的优先级项

指定视图名称Specifying a view name

在某些情况下,复杂的视图组件可能需要指定非默认视图。A complex view component might need to specify a non-default view under some conditions. 以下代码显示如何从 InvokeAsync 方法指定“PVC”视图。The following code shows how to specify the "PVC" view from the InvokeAsync method. 更新 PriorityListViewComponent 类中的 InvokeAsync 方法。Update the InvokeAsync method in the PriorityListViewComponent class.

public async Task<IViewComponentResult> InvokeAsync(
    int maxPriority, bool isDone)
{
    string MyView = "Default";
    // If asking for all completed tasks, render with the "PVC" view.
    if (maxPriority > 3 && isDone == true)
    {
        MyView = "PVC";
    }
    var items = await GetItemsAsync(maxPriority, isDone);
    return View(MyView, items);
}

将 Views/Shared/Components/PriorityList/Default.cshtml 文件复制到名为 Views/Shared/Components/PriorityList/PVC.cshtml 的视图。Copy the Views/Shared/Components/PriorityList/Default.cshtml file to a view named Views/Shared/Components/PriorityList/PVC.cshtml. 添加标题以指示正在使用 PVC 视图。Add a heading to indicate the PVC view is being used.

@model IEnumerable<ViewComponentSample.Models.TodoItem>

<h2> PVC Named Priority Component View</h2>
<h4>@ViewBag.PriorityMessage</h4>
<ul>
    @foreach (var todo in Model)
    {
        <li>@todo.Name</li>
    }
</ul>

更新 Views/ToDo/Index.cshtml:Update Views/ToDo/Index.cshtml:

@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })

运行应用并验证 PVC 视图。Run the app and verify PVC view.

优先级视图组件

如果不呈现 PVC 视图,请验证是否调用优先级为 4 或更高的视图组件。If the PVC view isn't rendered, verify you are calling the view component with a priority of 4 or higher.

检查视图路径Examine the view path

  • 将优先级参数更改为 3 或更低,从而不返回优先级视图。Change the priority parameter to three or less so the priority view isn't returned.

  • 将 Views/ToDo/Components/PriorityList/Default.cshtml 暂时重命名为 1Default.cshtml。Temporarily rename the Views/ToDo/Components/PriorityList/Default.cshtml to 1Default.cshtml.

  • 测试应用,你将收到以下错误:Test the app, you'll get the following error:

    An unhandled exception occurred while processing the request.
    InvalidOperationException: The view 'Components/PriorityList/Default' wasn't found. The following locations were searched:
    /Views/ToDo/Components/PriorityList/Default.cshtml
    /Views/Shared/Components/PriorityList/Default.cshtml
    EnsureSuccessful
    
  • 将 Views/ToDo/Components/PriorityList/1Default.cshtml 复制到 Views/Shared/Components/PriorityList/Default.cshtml。Copy Views/ToDo/Components/PriorityList/1Default.cshtml to Views/Shared/Components/PriorityList/Default.cshtml.

  • 将一些标记添加到共享 ToDo 视图组件视图,以指示视图来自“Shared”文件夹。Add some markup to the Shared ToDo view component view to indicate the view is from the Shared folder.

  • 测试“共享”组件视图。Test the Shared component view.

有共享组件视图的 ToDo 输出

避免使用硬编码字符串Avoiding hard-coded strings

若要确保编译时的安全性,可以用类名替换硬编码的视图组件名称。If you want compile time safety, you can replace the hard-coded view component name with the class name. 创建没有“ViewComponent”后缀的视图组件:Create the view component without the "ViewComponent" suffix:

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ViewComponentSample.Models;

namespace ViewComponentSample.ViewComponents
{
    public class PriorityList : ViewComponent
    {
        private readonly ToDoContext db;

        public PriorityList(ToDoContext context)
        {
            db = context;
        }

        public async Task<IViewComponentResult> InvokeAsync(
        int maxPriority, bool isDone)
        {
            var items = await GetItemsAsync(maxPriority, isDone);
            return View(items);
        }
        private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
        {
            return db.ToDo.Where(x => x.IsDone == isDone &&
                                 x.Priority <= maxPriority).ToListAsync();
        }
    }
}

using 视图文件添加语句 Razor ,并使用 nameof 运算符:Add a using statement to your Razor view file, and use the nameof operator:

@using ViewComponentSample.Models
@using ViewComponentSample.ViewComponents
@model IEnumerable<TodoItem>

    <h2>ToDo nameof</h2>
    <!-- Markup removed for brevity.  -->

    <div>

        @*
            Note: 
            To use the below line, you need to #define no_suffix in ViewComponents/PriorityList.cs or it won't compile.
            By doing so it will cause a problem to index as there will be multiple viewcomponents 
            with the same name after the compiler removes the suffix "ViewComponent"
        *@

        @*@await Component.InvokeAsync(nameof(PriorityList), new { maxPriority = 4, isDone = true })*@
    </div>

执行同步工作Perform synchronous work

如果不需要执行异步工作,框架将处理调用同步 Invoke 方法。The framework handles invoking a synchronous Invoke method if you don't need to perform asynchronous work. 以下方法将创建同步 Invoke 视图组件:The following method creates a synchronous Invoke view component:

public class PriorityList : ViewComponent
{
    public IViewComponentResult Invoke(int maxPriority, bool isDone)
    {
        var items = new List<string> { $"maxPriority: {maxPriority}", $"isDone: {isDone}" };
        return View(items);
    }
}

视图组件的 Razor 文件列出传递给方法的字符串 Invoke (Views/Home/component/PriorityList/) :The view component's Razor file lists the strings passed to the Invoke method (Views/Home/Components/PriorityList/Default.cshtml):

@model List<string>

<h3>Priority Items</h3>
<ul>
    @foreach (var item in Model)
    {
        <li>@item</li>
    }
</ul>

视图组件在文件中调用 Razor (例如, Views/Home/) 使用以下方法之一:The view component is invoked in a Razor file (for example, Views/Home/Index.cshtml) using one of the following approaches:

若要使用 IViewComponentHelper 方法,请调用 Component.InvokeAsyncTo use the IViewComponentHelper approach, call Component.InvokeAsync:

视图组件在文件中调用 Razor (例如, Views/Home/索引) 使用 IViewComponentHelperThe view component is invoked in a Razor file (for example, Views/Home/Index.cshtml) with IViewComponentHelper.

调用 Component.InvokeAsyncCall Component.InvokeAsync:

@await Component.InvokeAsync(nameof(PriorityList), new { maxPriority = 4, isDone = true })

若要使用标记帮助程序,请使用 @addTagHelper 指令注册包含视图组件的程序集(视图组件位于名为 MyWebApp 的程序集中):To use the Tag Helper, register the assembly containing the View Component using the @addTagHelper directive (the view component is in an assembly called MyWebApp):

@addTagHelper *, MyWebApp

使用标记文件中的 "查看组件标记帮助器" Razor :Use the view component Tag Helper in the Razor markup file:

<vc:priority-list max-priority="999" is-done="false">
</vc:priority-list>

的方法签名 PriorityList.Invoke 是同步的,但会 Razor Component.InvokeAsync 在标记文件中查找并调用方法。The method signature of PriorityList.Invoke is synchronous, but Razor finds and calls the method with Component.InvokeAsync in the markup file.

所有视图组件参数都是必需的All view component parameters are required

视图组件中的每个参数都是必需的属性。Each parameter in a view component is a required attribute. 请参阅此 GitHub 问题See this GitHub issue. 如果省略任何参数:If any parameter is omitted:

  • InvokeAsync 方法签名不匹配,因此该方法将不会执行。The InvokeAsync method signature won't match, therefore the method won't execute.
  • ViewComponent 不会呈现任何标记。The ViewComponent won't render any markup.
  • 不会引发任何错误。No errors will be thrown.

其他资源Additional resources