问题

如何在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请求,也没有控制器的生命周期,这就意味着在视图组件中不能使用过滤器和模型绑定。

视图组件可以使用依赖注入,这使得它们更加强大和易于测试。

创建

有很多方法创建视图组件,我们会讨论最常用到的选项:

  1. 创建一个类(放到项目中的任意位置),使其继承自抽象基类ViewComponent。

    • 按照约定,请将类名以ViewComponent结尾。
  2. 创建一个返回IViewComponentResult的方法Invoke。
    • 这个方法可以接受任意数量的参数,这些参数会在调用视图组件时传入。
  3. 将基类ViewComponent的方法View()作为Invoke的返回值,你也可以向其中传入自定义模型。
    • 可选的,你也可以在参数中指定视图页面的名称。

基类ViewComponent通过属性公开了很多有用的细节,比如HttpContext,RouteData,IUrlHelper,IPrincipal和ViewData。

调用

可以通过两种方式调用视图组件:

  1. 在视图页面中调用@await Component.InvokeAsync(component, parameters)
  2. 在控制器方法中,返回ViewComponent(component, parameters)

上面调用中的component是一个指向组件类的字符串。

当调用视图组件时,InvokeAsync()方法可以接受任意数量的参数,这些参数可以通过匿名对象传入。

发现

ASP.NET Core会按照如下顺序查找视图组件的Razor页面:

  1. Views/[controller]/Components/[component]/[view].cshtml
  2. Views/Shared/Components/[component]/[view].cshtml

其中[component]匹配如下规则:

  1. 除去ViewComponent后缀的组件名。
  2. 视图组件类上面[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 视图组件的更多相关文章

  1. [译]ASP.NET Core 2.0 视图引擎

    问题 如何在ASP.NET Core 2.0中使用Razor引擎来创建视图? 答案 新建一个空项目,修改Startup.cs,添加MVC服务和请求中间件: public void ConfigureS ...

  2. [译]ASP.NET Core 2.0 系列文章目录

    基础篇 [译]ASP.NET Core 2.0 中间件 [译]ASP.NET Core 2.0 带初始参数的中间件 [译]ASP.NET Core 2.0 依赖注入 [译]ASP.NET Core 2 ...

  3. [译]ASP.NET Core 2.0 部分视图

    问题 如何在ASP.NET Core 2.0中使用部分视图来重用页面的公共部分? 答案 新建一个空项目,在Startup中添加MVC服务和中间件: public void ConfigureServi ...

  4. [译]ASP.NET Core 2.0 路由引擎之网址生成

    问题 如何在ASP.NET Core 2.0中由路由引擎来生成网址? 答案 新建一个空项目,修改Startup.cs文件,添加MVC服务和中间件: public void ConfigureServi ...

  5. [译]ASP.NET Core 2.0 中间件

    问题 如何创建一个最简单的ASP.NET Core中间件? 答案 使用VS创建一个ASP.NET Core 2.0的空项目,注意Startup.cs中的Configure()方法: public vo ...

  6. [译]ASP.NET Core 2.0 布局页面

    问题 如何在ASP.NET Core 2.0项目中共享可见元素.代码块和指令? 答案 新建一个空项目,首先添加GreetingService服务和UserViewModel模型: public int ...

  7. [译]ASP.NET Core 2.0 区域

    问题 如何将一个规模庞大的ASP.NET Core 2.0应用程序进行逻辑分组? 答案 新建一个ASP.NET Core 2.0空项目,修改Startup类,增加Mvc服务和中间件: public v ...

  8. [译]ASP.NET Core 2.0 带初始参数的中间件

    问题 如何在ASP.NET Core 2.0向中间件传入初始参数? 答案 在一个空项目中,创建一个POCO(Plain Old CLR Object)来保存中间件所需的参数: public class ...

  9. [译]ASP.NET Core 2.0 全局配置项

    问题 如何在 ASP.NET Core 2.0 应用程序中读取全局配置项? 答案 首先新建一个空项目,并添加两个配置文件: 1. appsettings.json { "Section1&q ...

随机推荐

  1. http://codeforces.com/contest/349

    A. Cinema Line time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  2. Reliability diagrams

    Reliability diagrams (Hartmann et al. 2002) are simply graphs of the Observed frequency of an event ...

  3. GRE 协议简介

    1. 协议简介    gre(generic routing encapsulation,通用路由封装)协议是对某些网络层协议(如ip 和ipx)的数据报进行封装,使这些被封装的数据报能够在另一个网络 ...

  4. Ubuntu12.04 Firefox安装flash

    1. 实验环境 Ubuntu 14.04x86 2.安装步骤 2.1 浏览器访问:https://get.adobe.com/flashplayer/?loc=cn 2.2 网址会自动识别ubuntu ...

  5. ZOJ2105 终于找到错误

    ZOJ2105:点击打开链接 错误代码 #include<stdio.h> #include<stdlib.h> int q[110]; int main() { int a, ...

  6. Oracle虚拟机VirtualBox安装成功后的注意事项

    首先VirtualBox的安装教程 (1)按文档安装 (2)安装完之后配置共享文件夹 (3)安装windowxp镜像 (4)安装Oracle  详情请见Oracle安装文档 (5)启动xp虚拟机 (6 ...

  7. OpenGL ES2.0光照

    一.简单光照原理 平行光(正常光) 光照效果=   环境颜色 + 漫反射颜色 + 镜面反射颜色 点光源 光照效果=   环境颜色 + (漫反射颜色 + 镜面反射颜色)× 衰减因子 聚光灯 光照效果= ...

  8. iOS自动化环境搭建——macaca

    macaca-java for ios 自动化环境搭建 基础原理解析:https://testerhome.com/topics/6608 一.环境搭建 1.安装eclipse; -----Java开 ...

  9. Django实现简单分页功能

    使用django的第三方模块django-pure-pagination 安装模块: pip install django-pure-pagination 将'pure_pagination'添加到s ...

  10. uva 10118,记忆化搜索

    这个题debug了长达3个小时,acm我不能放弃,我又回来了的第一题! 一开始思路正确,写法不行,结果越改越乱 看了网上某神的代码,学习了一下 coding+debug:4小时左右,记忆化搜索+dp类 ...