为了账号安全,请及时绑定邮箱和手机立即绑定

关于ASP.NET Core 2.0 的视图组件

标签:
C#

如何在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结尾。

  • 创建一个返回IViewComponentResult的方法Invoke。

    • 这个方法可以接受任意数量的参数,这些参数会在调用视图组件时传入。

  • 将基类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页面,此时会有异常,从而我们能够清楚看到系统的查找顺序:

    点击查看更多内容
    1人点赞

    若觉得本文不错,就分享一下吧!

    评论

    作者其他优质文章

    正在加载中
    感谢您的支持,我会继续努力的~
    扫码打赏,你说多少就多少
    赞赏金额会直接到老师账户
    支付方式
    打开微信扫一扫,即可进行扫码打赏哦
    今天注册有机会得

    100积分直接送

    付费专栏免费学

    大额优惠券免费领

    立即参与 放弃机会
    意见反馈 帮助中心 APP下载
    官方微信

    举报

    0/150
    提交
    取消