ASP.NET Core Razor 视图组件

视图组件简介

在新的ASP.NET Core MVC中,视图组件类似于局部视图,但它们更强大。视图组件不使用模型绑定,仅依赖于您在调用时提供的数据。

视图组件特性:

  • 呈现页面响应的某一部分而不是整个响应

  • 包括在控制器和视图之间发现的关注分离和可测试性优势

  • 可以具有参数和业务逻辑

  • 通常在页面布局中调用

视图组件是在任何地方可重用的呈现逻辑,对于局部视图来说相对复杂,例如:

  • 动态导航菜单

  • 标签云(查询数据库)

  • 登录面板

  • 购物车

  • 最近发表的文章

  • 典型博客上的侧边栏内容

  • 将在每个页面上呈现的登录面板,并显示要注销或登录的链接,具体取决于用户的登录状态

视图组件由两部分组成:类(通常继承自ViewComponent)和返回的结果(通常是视图)。像控制器一样,视图组件可以是POCO,但大多数开发人员都希望利用从ViewComponent继承的方法和属性。

创建视图组件

此部分包含创建视图组件的高级功能。在本文的后面,我们将详细介绍每一个步骤,并创建一个视图组件。

视图组件类

视图组件类可以通过以下任何方式来创建:

  • 继承自 ViewComponent 类

  • 使用[ViewComponent]特性来标记一个类,或者继承自具有[ViewComponent]特性的类

  • 创建类的名称以 ViewComponent 后缀结尾

与控制器一样,视图组件必须是公共、非嵌套、非抽象类。视图组件名称是删除“ViewComponent”后缀的类名称,也可以使用ViewComponentAttribute.Name属性显式指定名称。

视图组件类特性:

  • 完美支持构造函数依赖注入

  • 不参与控制器生命周期,这意味着您不能在视图组件中使用过滤器

视图组件方法

视图组件在InvokeAsync方法中定义逻辑,并返回IViewComponentResult类型。参数直接来自视图组件的调用,而不是模型绑定;视图组件从不直接处理请求;通常视图组件会初始化模型,并通过调用View方法将其传递给视图。总而言之,视图组件方法特性:

  • 定义一个返回IViewComponentResultInvokeAsync方法

  • 通常会初始化一个模型,并通过调用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>/  .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方法返回满足isDonemaxPriority参数的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

相关文章: 

  • .NET Core 2.0 正式发布信息汇总

  • .NET Standard 2.0 特性介绍和使用指南

  • .NET Core 2.0 的dll实时更新、https、依赖包变更问题及解决

  • .NET Core 2.0 特性介绍和使用指南

  • Entity Framework Core 2.0 新特性

  • 体验 PHP under .NET Core

  • .NET Core 2.0使用NLog

  • 升级项目到.NET Core 2.0,在Linux上安装Docker,并成功部署

  • 解决Visual Studio For Mac Restore失败的问题

  • ASP.NET Core 2.0 特性介绍和使用指南

  • .Net Core下通过Proxy 模式 使用 WCF

  • .NET Core 2.0 开源Office组件 NPOI

  • ASP.NET Core - Razor页面之Handlers处理方法

  • ASP.NET Core Razor页面 vs MVC

  • Razor Page–Asp.Net Core 2.0新功能  Razor Page介绍

  • ASP.Net Core 2.0中的Razor Page不是WebForm

原文地址:http://www.cnblogs.com/tdfblog/p/view-components-in-asp-net-core.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/323666.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三个好用的并发工具类

转载自 三个好用的并发工具类 以前的文章中&#xff0c;我们介绍了太多的底层原理技术以及新概念&#xff0c;本篇我们轻松点&#xff0c;了解下 Java 并发包下、基于这些底层原理的三个框架工具类。 它们分别是&#xff1a; 信号量 Semaphore 倒计时门栓 CountDownLatch …

Error Handling in ASP.NET Core

前言 在程序中&#xff0c;经常需要处理比如 404&#xff0c;500 &#xff0c;502等错误&#xff0c;如果直接返回错误的调用堆栈的具体信息&#xff0c;显然大部分的用户看到是一脸懵逼的&#xff0c;你应该需要给用户返回那些看得懂的界面。比如&#xff0c;“当前页面不存在…

基于python的selenium

一.安装 安装WebDriver 查看chrome版本号&#xff0c;设置-帮助-关于Google chrome&#xff0c;找到版本号。 可以到这个网站进行下载对应版本的chromedriver,如果chrome浏览器版本过高,可以下载最新版的chromedriver进行使用 Chrome for Testing availability 下载下来之后…

多信息登录、检测用户信息是否完善且引导补全

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注&#xff1a;穆雄雄的博客 前言 现在是2022年4月28日13:41:29&#xff01; 今天分享两块内容。 1.需求&#xff1a;用户可以通过手机号、邮箱来注册我们的系统&#xff0c;用户完成之后&#xff0c;可以去完善自己的个人信息…

PNG 图片压缩原理解析

转载自 PNG 图片压缩原理解析 什么是PNG PNG的全称叫便携式网络图型&#xff08;Portable Network Graphics&#xff09;是目前最流行的网络传输和展示的图片格式&#xff0c;原因有如下几点&#xff1a; 无损压缩&#xff1a;PNG图片采取了基于LZ77派生算法对文件进行压缩&…

element ui实现多层级复杂表单的操作(添加与回显)之表单操作交互操作

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 前言 现在是2022年5月3日11:47:15&#xff01;劳动节假期已经过去了三天了&#xff0c;今天是被封家里的第7天&#xff0c;也是解封的第一天。 说实话&#xff0c;在家里的工作效率一点都…

TypeScript 2.5 发布,增加语言级重构

在 TypeScript 2.5 版本中&#xff0c;Microsoft 专注于提高开发人员的生产力&#xff0c;其范围已经超出了代码编辑器所提供的常见功能。 习惯于类型语言&#xff08;如 C&#xff03;&#xff09;的开发人员喜欢使用那些可以轻松执行常见重构的工具。现在 TypeScript 可以利…

element ui实现多层级复杂表单的操作(添加与回显)之添加功能实现

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 前言 现在是2022年5月3日13:35:15&#xff01;文接上篇。[element ui实现多层级复杂表单的操作&#xff08;添加与回显&#xff09;之表单操作交互操作](element ui实现多层级复杂表单的操…

Entity Framework Core Like 查询揭秘

在Entity Framework Core 2.0中增加一个很酷的功能&#xff1a;EF.Functions.Like()&#xff0c;最终解析为SQL中的Like语句&#xff0c;以便于在 LINQ 查询中直接调用。 不过Entity Framework 中默认提供了StartsWith、Contains和EndsWith方法用于解决模糊查询&#xff0c;那…

element ui实现多层级复杂表单的操作(添加与回显)之回显功能实现

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 前言 现在是2022年5月3日17:02:30&#xff01;文接上两篇。 [element ui实现多层级复杂表单的操作&#xff08;添加与回显&#xff09;之表单操作交互操作](element ui实现多层级复杂表单…

在Mac的Docker中运行DotNetCore2.0

最近学习Angular4&#xff0c;服务端准备使用DotNetCore API来实现&#xff0c;本文简单介绍下在Mac中怎样将DotNetCore程序部署在Docker中&#xff0c;并使用Nginx做反向代理让程序可以跑起来。 具体步骤如下 安装Docker拉取DotNetCore镜像使用VS For Mac创建DotNetCore应用…

springboot实现复杂业务下的更新操作

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 前言 现在是2022年5月4日19:25:55&#xff01;今天写了个这样的功能&#xff1a; 某用户在一天内有多个训练项目&#xff0c;比如&#xff1a;晨跑&#xff0c;有氧训练&#xff0c;跳绳这…

elementui解决el-dialog不清空内容的问题,el-dialog关闭时销毁子组件

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 前言 现在是2022年5月5日22:48:21&#xff01; 今天在使用element-ui中的el-dialog的时候遇到了个这样的问题&#xff1a;页面上点击添加的按钮&#xff0c;弹出el-dialog对话框&#xff…

MySQL 中的重做日志,回滚日志以及二进制日志的简单总结

转载自 MySQL 中的重做日志&#xff0c;回滚日志以及二进制日志的简单总结 MySQL中有六种日志文件&#xff0c;分别是&#xff1a;重做日志&#xff08;redo log&#xff09;、回滚日志&#xff08;undo log&#xff09;、二进制日志&#xff08;binlog&#xff09;、错误日志…

c语言分离三位数

#include<stdio.h> main(){ int k,l,m,n;printf("请输入一个三位数"); scanf("%d",&k);lk/100;mk/10%10;nk%10;printf("这个三位数的百位是:%d\n",l);printf("这个三位数的十位是:%d\n",m);printf("这个三位数的个位是…

分布式ID自增算法 Snowflake

近在尝试EF的多数据库移植&#xff0c;但是原始项目中主键用的Sqlserver的GUID。MySQL没法移植了。 其实发现GUID也没法保证数据的递增性&#xff0c;又不太想使用int递增主键&#xff0c;就开始探索别的ID形式。 后来发现twitter的Snowflake算法。 一开始我尝试过直接引用N…

java中,根据指定日期显示出前n天的日期

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 今天分享的是&#xff1a;在java中&#xff0c;根据指定日期显示出前n天的日期 效果如下&#xff1a; 大家注意观察上面的时间&#xff0c;我传入的时间是&#xff1a;2022年5月9日21:28:…

jdbc实现批量给多个表中更新数据(解析Excel表数据插入到数据库中)

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 前言 现在是&#xff1a;2022年5月19日08:01:51 今天遇到了个这样的需求&#xff0c;解析excel表中的数据&#xff0c;以JDBC的方式&#xff0c;将数据批量更新至不同的数据表中。注意&am…

.Net Core 全局配置读取管理方法 ConfigurationManager

最近在学习.Net Core的过程中&#xff0c;发现.Net Framework中常用的ConfigurationManager在Core中竟然被干掉了。 也能理解。Core中使用的配置文件全是Json&#xff0c;不像Framework使用的XML&#xff0c;暂时不支持也是能理解的&#xff0c;但是毕竟全局配置文件这种东西还…

Http 持久连接与 HttpClient 连接池

转载自 Http 持久连接与 HttpClient 连接池 一、背景 HTTP协议是无状态的协议&#xff0c;即每一次请求都是互相独立的。因此它的最初实现是&#xff0c;每一个http请求都会打开一个tcp socket连接&#xff0c;当交互完毕后会关闭这个连接。 HTTP协议是全双工的协议&#x…