ASP.NET Core Razor 视图组件
视图组件简介
在新的ASP.NET Core MVC中,视图组件类似于局部视图,但它们更强大。视图组件不使用模型绑定,仅依赖于您在调用时提供的数据。
视图组件特性:
- 呈现页面响应的某一部分而不是整个响应
- 包括在控制器和视图之间发现的关注分离和可测试性优势
- 可以具有参数和业务逻辑
- 通常在页面布局中调用
视图组件是在任何地方可重用的呈现逻辑,对于局部视图来说相对复杂,例如:
- 动态导航菜单
- 标签云(查询数据库)
- 登录面板
- 购物车
- 最近发表的文章
- 典型博客上的侧边栏内容
- 将在每个页面上呈现的登录面板,并显示要注销或登录的链接,具体取决于用户的登录状态
视图组件由两部分组成:类(通常继承自ViewComponent)和返回的结果(通常是视图)。像控制器一样,视图组件可以是POCO,但大多数开发人员都希望利用从ViewComponent继承的方法和属性。
创建视图组件
此部分包含创建视图组件的高级功能。在本文的后面,我们将详细介绍每一个步骤,并创建一个视图组件。
视图组件类
视图组件类可以通过以下任何方式来创建:
- 继承自 ViewComponent 类
- 使用
[ViewComponent]特性来标记一个类,或者继承自具有[ViewComponent]特性的类 - 创建类的名称以 ViewComponent 后缀结尾
与控制器一样,视图组件必须是公共、非嵌套、非抽象类。视图组件名称是删除“ViewComponent”后缀的类名称,也可以使用ViewComponentAttribute.Name属性显式指定名称。
视图组件类特性:
视图组件方法
视图组件在InvokeAsync方法中定义逻辑,并返回IViewComponentResult类型。参数直接来自视图组件的调用,而不是模型绑定;视图组件从不直接处理请求;通常视图组件会初始化模型,并通过调用View方法将其传递给视图。总而言之,视图组件方法特性:
- 定义一个返回
IViewComponentResult的InvokeAsync方法 - 通常会初始化一个模型,并通过调用
ViewComponent类型的View方法将其传递给视图 - 参数来自调用方法,而不是HTTP请求,没有模型绑定
- 不能直接通过HTTP请求访问,它们通常在视图中通过代码调用;视图组件永远不会处理请求
- 在方法签名上重载,而不是当前HTTP请求的任何详细信息
查找视图路径
运行时在以下路径中搜索视图:
- Views/<controller_name>/Components/<view_component_name>/<view_name>
- Views/Shared/Components/<view_component_name>/<view_name>
视图组件的视图名称默认为Default,这意味着您的视图文件通常将命名为Default.cshtml。创建视图组件结果或调用View方法时,可以指定不同的视图名称。
我们建议您视图文件命名为Default.cshtml,并使用Views/Shared/Components/<view_component_name>/\ <view_name>.cshtml路径。此示例中使用的PriorityList视图组件,视图的路径是Views/Shared/Components/PriorityList/Default.cshtml。
调用视图组件
要使用视图组件,请在视图中调用以下代码:
@Component.InvokeAsync("Name of view component", <anonymous type containing parameters>)
参数将被传递给InvokeAsync方法,在本文中编写的PriorityList视图组件在Views/Todo/Index.cshtml视图文件中调用。在下文中,使用两个参数调用InvokeAsync方法:
@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })
通过标签帮助器调用视图组件
对于ASP.NET Core 1.1及更高版本,您可以将视图组件作为标签帮助器(Tag Helper)进行调用:
<vc:priority-list max-priority="2" is-done="false">
</vc:priority-list>
标签帮助器将Pascal命名方式的类型和方法参数被转换成它们的小写短横线命名方式(lower kebab case)。调用视图组件的标签帮助器使用该元素,视图组件约定如下:
<vc:[view-component-name]
parameter1="parameter1 value"
parameter2="parameter2 value">
</vc:[view-component-name]>
注意:为了将视图组件作为标签帮助器,您必须使用@addTagHelper指令注册包含视图组件的程序集。例如,如果您的视图组件位于名为“MyWebApp”的程序集中,请将以下指令添加到_ViewImports.cshtml文件中:
@addTagHelper *, MyWebApp
您可以将视图组件作为标签帮助器注册到引用视图组件的任何文件。有关如何注册标签助手的更多信息,请参阅Managing Tag Helper Scope。
本示例中使用的InvokeAsync方法:
@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })
标签帮助器标记:
<vc:priority-list max-priority="2" is-done="false">
</vc:priority-list>
在上面的示例中,PriorityList视图组件变为priority-list;视图组件的参数作为属性按小写短横线命名方式传递。
从控制器直接调用视图组件
视图组件通常在视图调用,但您也可以直接在控制器的方法中调用它们。虽然视图组件被定义为不能像控制器一样直接处理请求,但您可以轻松在控制器的Action方法中实现返回ViewComponentResult内容。
在下面的示例中,在控制器直接调用视图组件:
public IActionResult IndexVC()
{
return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}
演练:创建一个简单的视图组件
示例下载,构建和测试入门代码。这是一个简单的项目,Todo控制器显示 Todo 项目列表。

添加ViewComponent类
创建一个 ViewComponents 文件夹并添加以下PriorityListViewComponent类:
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();
}
}
}
代码注意事项:
- 视图组件类可以包含在项目中的任何文件夹中。
- 因为类名称PriorityListViewComponent以后缀ViewComponent结尾,运行时在视图中引用视图组件时使用字符串“PriorityList”。稍后我会详细解释一下。
[ViewComponent]特性可以更改用于引用视图组件的名称。例如,我们可以该类命名为XYZ并应用该ViewComponent属性:[ViewComponent(Name = "PriorityList")]
public class XYZ : ViewComponent
[ViewComponent]特性告诉视图组件选择器在查找与组件关联的视图时使用名称PriorityList,并在从视图引用组件类时使用字符串“PriorityList”。稍后我会详细解释一下。- 组件使用依赖注入来使
DbContext可用。 InvokeAsync是一个可以从视图中调用的公开方法,它可以使用任意数量的参数。InvokeAsync方法返回满足isDone和maxPriority参数的ToDo集合。
创建视图组件Razor视图
- 创建
Views/Shared/Components文件夹,此文件夹必须命名为 Components。 - 创建 Views/Shared/Components/PriorityList 文件夹。此文件夹名称必须与视图组件类的名称一致,或者类名称去掉后缀(如果遵循约定在类名称中使用
ViewComponent后缀)。如果您使用该ViewComponent特性,则名称需要与特性名称一致。 - 创建一个Views/Shared/Components/PriorityList/Default.cshtml Razor视图:
@model IEnumerable<ViewComponentSample.Models.TodoItem> <h3>Priority Items</h3>
<ul>
@foreach (var todo in Model)
{
<li>@todo.Name</li>
}
</ul>
Razor视图会列出
TodoItem并显示它们。如果视图组件InvokeAsync方法未传递视图的名称(如我们的示例中),则按照约定视图名称为 Default。在本文的后面,我将向您展示如何传递视图的名称。如果视图组件只适用于特定控制器,则可以将其添加到控制器特定的文件夹(Views/Todo/Components/PriorityList/Default.cshtml)。 - 在视图 Views/Todo/index.cshtml 文件底部的
div元素中包含视图组件的调用<div >
@await Component.InvokeAsync("PriorityList", new { maxPriority = 2, isDone = false })
</div>
@await Component.InvokeAsync是调用视图组件的语法。第一个参数是我们要调用组件的名称,随后是传递给组件的参数。InvokeAsync可以包含任意数量的参数。
调试应用程序,下图显示了ToDo列表和选择项:

您也可以直接在控制器中调用视图组件:
public IActionResult IndexVC()
{
return ViewComponent("PriorityList", new { maxPriority = 3, isDone = false });
}

指定视图名称
复杂视图组件可能需要在某些情况下指定非默认视图。以下代码显示了如何从InvokeAsync方法中指定“PVC”视图。修改PriorityListViewComponent类中的InvokeAsync方法。
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 视图文件。添加标题以表示正在使用的是PVC视图。
@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/TodoList/Index.cshtml:
@await Component.InvokeAsync("PriorityList", new { maxPriority = 4, isDone = true })
运行应用程序并验证是PVC视图。

如果显示不是PVC视图,请验证您调用视图组件priority参数是否为4或更高的。
检测视图路径
- 将
priority参数更改为三个或更小,返回默认视图。 - 临时将 Views/Todo/Components/PriorityList/Default.cshtml 重命名为 1Default.cshtml。
- 调试应用程序,您将收到以下错误:
An unhandled exception occurred while processing the request.
InvalidOperationException: The view 'Components/PriorityList/Default' was not 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 。
- 在 Shared 的Todo视图组件视图中添加一些标记,以表示视图来自 Shared 文件夹。
- 测试 Shared 组件视图。

避免字符串魔法
如果要编译时安全,则可以使用类名替换硬编码视图组件名称。创建没有以“ViewComponent”后缀的视图组件:
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运算符:
@using ViewComponentSample.Models
@using ViewComponentSample.ViewComponents
@model IEnumerable<TodoItem>
<h2>ToDo nameof</h2>
<div>
@await Component.InvokeAsync(nameof(PriorityList), new { maxPriority = 4, isDone = true })
</div>
其它资源
原文:《View components》https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components
翻译:Sweet Tang
本文地址:http://www.cnblogs.com/tdfblog/p/view-components-in-asp-net-core.html
欢迎转载,请在明显位置给出出处及链接。
ASP.NET Core Razor 视图组件的更多相关文章
- ASP.NET Core Razor 视图导入 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core Razor 视图导入 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Razor 视图导入 上一章节我们介绍了视图起始页,学习 ...
- ASP.NET Core Razor 视图起始页 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core Razor 视图起始页 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Razor 视图起始页 上一章节中我们介绍了布局视图, ...
- ASP.NET CORE 自定义视图组件(ViewComponent)注意事项
*红色字体为固定命名,蓝色为一般命名规则,黄色为ASP.NET CORE 默认查找文件名 概要:1.简单ViewComponent的用法 2.ViewComponent控制器返回值 3.注意事项 1 ...
- ASP.NET Core Razor 视图预编译、动态编译
0x01 前言 ASP.NET Core在默认发布情况下,会启动预编译将试图编译成xx.Views.dll,也许在视图中打算修改一处很细小的地方我们需要再重新编译视图进行发布.下面我将从 ASP.NE ...
- ASP.NET Core Razor 布局视图 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core Razor 布局视图 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Razor 布局视图 上一章节中我们学习了如何使用 EF ...
- ASP.NET Core - Razor 页面简介
简介 随着ASP.NET Core 2 即将来临,最热门的新事物是Razor页面.在之前的一篇文章中,我们简要介绍了ASP.NET Core Razor 页面. Razor页面是ASP.NET Cor ...
- ASP.NET Core Razor 页面使用指南
ASP.NET Core Razor 页面作为 ASP.NET Core 2.0的一部分发布,它是基于页面的全新的Web开发框架.如果您想学习如何使用 ASP.NET Core Razor 页面,可以 ...
- 学习ASP.NET Core Razor 编程系列十九——分页
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- ASP.NET Core - Razor 页面介绍
简介 随着ASP.NET Core 2 即将来临,最热门的新事物是Razor页面.在之前的一篇文章中,我们简要介绍了ASP.NET Core Razor 页面. Razor页面是ASP.NET Cor ...
随机推荐
- STM32初学Keil4编译时出现 Error:Failed to execute 'BIN40/Armcc'
一种是在系统开始--运行里输入cmd,查看armcc状态.详情见推文: http://blog.csdn.net/hicui/article/details/7350805(笔记记录,请勿见怪) 都没 ...
- MongoDB入门命令
查看所有数据库 > show dbs admin (empty) local 0.078GB > admin和管理相关, admin和local数据库不要轻易动 选择库 > use ...
- 在Mac OS 下 build Tesseract4.0 源码并在命令行中使用
作者电脑:Mac Mini 系统信息:OS X EI Capitan 10.11.6 Tesseract4.0github地址:https://github.com/tesseract-ocr/tes ...
- H5投放在朋友圈广告做压力测试
一.环境 MacOS Sierra 二.背景 朋友圈广告投放的H5需要做ab压测,这里不赘述. 具体官方文档如下:http://ad.weixin.qq.com/learn/n10 三.正文 (1)别 ...
- akoj-1222-炸金花
炸金花 Time Limit:1000MS Memory Limit:65536K Total Submit:40 Accepted:19 Description 炸金花是一个风靡全球的扑克游戏,喜 ...
- 脱壳练习之bitarts 5.0
运行界面 一开始不是PUSHAD,这里我们跟到PUSHAD指令处,按F7执行该指令,接着在寄存器窗口中定位到ESP寄存器的值,在其上面单击鼠标右键选择-Follow in Dump. 仅允许非商业转载 ...
- C++中printf和scanf的用法
(一)printf的用法 printf:按格式打印,向控制台输出.print:打印 ,f:formate,格式化. 在使用printf向控制台输出时,不建议使用中文字符串,中文字符串的问题比较复杂,有 ...
- 设计模式(4)建造者模式/生成器模式(Builder)
设计模式(0)简单工厂模式 设计模式(1)单例模式(Singleton) 设计模式(2)工厂方法模式(Factory Method) 设计模式(3)抽象工厂模式(Abstract Factory) 源 ...
- request.getParameter() 和request.getAttribute() 区别
getParameter 是用来接受用post个get方法传递过来的参数的.getAttribute 必须先setAttribute.(1)request.getParameter() 取得是通过容器 ...
- SSM简明教程:简单的十步教你搭建人生第一个SSM框架[ SSM框架整合教程(Spring+SpringMVC+MyBatis) ]
SSM_BookSystem SSM框架基础 SSM_BookSystem ---> Hello CRUD 说明:本项目目前包含基础的CRUD 日期:2017-05-01 22:25:37 作者 ...