[译]ASP.NET Core 2.0 视图组件
问题
如何在ASP.NET Core 2.0中使用视图组件?
答案
新建一个空项目,修改Startup类并添加MVC服务和中间件:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
} public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
添加一个模型类:
public class UserInfoViewModel
{
public int UserId { get; set; }
public string UserName { get; set; }
public string LastLogin { get; set; }
}
添加继承自ViewComponent的自定义视图组件:
public class UserInfoViewComponent : ViewComponent
{
public IViewComponentResult Invoke(int userId)
{
var model = new UserInfoViewModel
{
UserId = userId,
UserName = "james@bond.com",
LastLogin = DateTime.Now.ToString()
};
return View(model);
}
}
添加视图组件对应的视图文件(Views/Shared/Components/UserInfo/Default.cshtml):
@using ViewComponents.Models
@model UserInfoViewModel <div style="border: 1px dotted blue; margin: 5px">
<h3>User Info</h3>
<p>UserId: @Model.UserId</p>
<p>UserName: @Model.UserName</p>
<p>Last Login: @Model.LastLogin</p>
</div>
添加一个控制器和相应的视图文件:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
@using ViewComponents.Models <div style="border: 1px solid black; margin: 5px">
<h2>Home/Index</h2>
@await Component.InvokeAsync("UserInfo", new { UserId = 5 })
</div>
现在,我们来看下解决方案的目录层次:

运行,此时页面显示:

讨论
视图组件是渲染到其他视图内部的一种特殊类型。对于重用视图中的公共部分或者将大的视图分隔成小组件都非常有用。
与部分视图不同,视图组件不依赖于控制器。它们有自己的类来控制组件用到的模型以及视图模板来生成最终呈现的HTML/CSS。
我喜欢把它们看作是小型控制器,尽管这并不完全正确,但是有助于我们了解它们的用法。和控制器不同,视图组件不处理HTTP请求,也没有控制器的生命周期,这就意味着在视图组件中不能使用过滤器和模型绑定。
视图组件可以使用依赖注入,这使得它们更加强大和易于测试。
创建
有很多方法创建视图组件,我们会讨论最常用到的选项:
- 创建一个类(放到项目中的任意位置),使其继承自抽象基类ViewComponent。
- 按照约定,请将类名以ViewComponent结尾。
- 创建一个返回IViewComponentResult的方法Invoke。
- 这个方法可以接受任意数量的参数,这些参数会在调用视图组件时传入。
- 将基类ViewComponent的方法View()作为Invoke的返回值,你也可以向其中传入自定义模型。
- 可选的,你也可以在参数中指定视图页面的名称。
基类ViewComponent通过属性公开了很多有用的细节,比如HttpContext,RouteData,IUrlHelper,IPrincipal和ViewData。
调用
可以通过两种方式调用视图组件:
- 在视图页面中调用@await Component.InvokeAsync(component, parameters)
- 在控制器方法中,返回ViewComponent(component, parameters)
上面调用中的component是一个指向组件类的字符串。
当调用视图组件时,InvokeAsync()方法可以接受任意数量的参数,这些参数可以通过匿名对象传入。
发现
ASP.NET Core会按照如下顺序查找视图组件的Razor页面:
- Views/[controller]/Components/[component]/[view].cshtml
- Views/Shared/Components/[component]/[view].cshtml
其中[component]匹配如下规则:
- 除去ViewComponent后缀的组件名。
- 视图组件类上面[ViewComponent]特性所指定的值
其中[view]缺省值是Default,当然我们也可以在视图组件的Invoke方法中返回特定的值。比如下面的组件指定视图名称为MyInfo.cshtml:
public IViewComponentResult Invoke(int userId)
{
var model = new UserInfoViewModel
{
UserId = userId,
UserName = "james@bond.com",
LastLogin = DateTime.Now.ToString()
};
return View("MyInfo", model);
}
本例中,如果我们删除视图组件对应的Razor页面,此时会有异常,从而我们能够清楚看到系统的查找顺序:

源代码下载
原文:https://tahirnaushad.com/2017/08/24/asp-net-core-2-0-mvc-view-components/
ASP.NET Core 2.0 系列文章目录
[译]ASP.NET Core 2.0 视图组件的更多相关文章
- [译]ASP.NET Core 2.0 视图引擎
问题 如何在ASP.NET Core 2.0中使用Razor引擎来创建视图? 答案 新建一个空项目,修改Startup.cs,添加MVC服务和请求中间件: public void ConfigureS ...
- [译]ASP.NET Core 2.0 系列文章目录
基础篇 [译]ASP.NET Core 2.0 中间件 [译]ASP.NET Core 2.0 带初始参数的中间件 [译]ASP.NET Core 2.0 依赖注入 [译]ASP.NET Core 2 ...
- [译]ASP.NET Core 2.0 部分视图
问题 如何在ASP.NET Core 2.0中使用部分视图来重用页面的公共部分? 答案 新建一个空项目,在Startup中添加MVC服务和中间件: public void ConfigureServi ...
- [译]ASP.NET Core 2.0 路由引擎之网址生成
问题 如何在ASP.NET Core 2.0中由路由引擎来生成网址? 答案 新建一个空项目,修改Startup.cs文件,添加MVC服务和中间件: public void ConfigureServi ...
- [译]ASP.NET Core 2.0 中间件
问题 如何创建一个最简单的ASP.NET Core中间件? 答案 使用VS创建一个ASP.NET Core 2.0的空项目,注意Startup.cs中的Configure()方法: public vo ...
- [译]ASP.NET Core 2.0 布局页面
问题 如何在ASP.NET Core 2.0项目中共享可见元素.代码块和指令? 答案 新建一个空项目,首先添加GreetingService服务和UserViewModel模型: public int ...
- [译]ASP.NET Core 2.0 区域
问题 如何将一个规模庞大的ASP.NET Core 2.0应用程序进行逻辑分组? 答案 新建一个ASP.NET Core 2.0空项目,修改Startup类,增加Mvc服务和中间件: public v ...
- [译]ASP.NET Core 2.0 带初始参数的中间件
问题 如何在ASP.NET Core 2.0向中间件传入初始参数? 答案 在一个空项目中,创建一个POCO(Plain Old CLR Object)来保存中间件所需的参数: public class ...
- [译]ASP.NET Core 2.0 全局配置项
问题 如何在 ASP.NET Core 2.0 应用程序中读取全局配置项? 答案 首先新建一个空项目,并添加两个配置文件: 1. appsettings.json { "Section1&q ...
随机推荐
- C++ sizeof 误区 大公司面试题
1.C++ 无成员变量和函数的类型的实例,求该实例的sizeof? 答:是1.(不是0) 2.如果在题1的基础上有1个成员变量,sizeof是(1+成员变量的大小)吗? 答:不是,是成员变量的大小. ...
- 【POJ】3090 Visible Lattice Points(欧拉函数)
Visible Lattice Points Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7705 Accepted: ...
- JS获取随机的16位十六进制的数
直接上代码: function getRamNumber(){ var result=''; for(var i=0;i<16;i++){ result+=Math.floor(Math.ran ...
- Ubuntu16.04下安装redis
Ubuntu16.04下安装redis 保证网络畅通,选定好下载工作路径,执行以下命令下载redis-3.2.6: sudo wget http://download.redis.io/release ...
- 【DDD】业务建模实践 —— 人关注人
社区业务领域中,存在‘人关注人’的场景,在这个场景中,关系较为复杂,且均表现在‘人’同一个业务实体上,因此,这个case的建模过程值得思考.本文将就‘人关注人’这个业务case的领域建模进行探讨,欢迎 ...
- 虚拟机+桥接模式+Host-only模式 搭建完美的Windows下Linux开发环境
相信有很多鞋童和我一个样是一枚Linux码农(我现在还是嵌入式方向). 做Linux开发势必需要一个Linux环境, 大多数开发者会首先选择一个Linux发行版, 其中Ubuntu LTS版本应该是选 ...
- 浅谈Java抽象类
什么是抽象类?这名字听着就挺抽象的,第一次听到这个名字还真有可能被唬住.但是,就像老人家所说的,一切反动派都是纸老虎,一切有着装x名字的概念也是纸老虎.好吧,我们已经从战略上做到了藐视它,现在就要战术 ...
- zabbix使用mysql数据库 对表分区
zabbix删除历史数据 mysql 表自动分区.删除 ----2016年终总结 二 zabbix清理历史数据是个比较蛋疼的问题,尤其在监控数据较多时,一方面无法彻底释放历史数据空间,一方面数据库删除 ...
- 吾八哥学Python(四):了解Python基础语法(下)
咱们接着上篇的语法学习,继续了解学习Python基础语法. 数据类型大体上把Python中的数据类型分为如下几类:Number(数字),String(字符串).List(列表).Dictionary( ...
- Amaze UI 是一个移动优先的跨屏前端框架。 http://amazeui.org/
http://amazeui.org/ Amaze UI 是一个移动优先的跨屏前端框架.... Amaze UI 以移动优先(Mobile first)为理念,从小屏逐步扩展到大屏,最终实现所有屏幕适 ...