NET Core 十种方式扩展你的 Views

原文地址:http://asp.net-hacker.rocks/2016/02/18/extending-razor-views.html
作者:Jürgen Gutsch
翻译:杨晓东(Savorboard)

现在,已经有很多种方式来扩展Razor视图了,我们循循渐进,先从最简单的开始。
如果你之前熟悉MVC5(以及之前的MVC)中的视图的话,有一部分你应该已经很熟悉了。在新的ASP.NET Core 中,那些你熟悉的方式有一部分仍然能用,只是Core版本针对视图又添加了一些东西。这篇文章,我们就来一起看看吧。

#1:数据视图(Typed Views)

这是一个不具有动态内容的最基本的一个视图,就是你定义一个ViewModel , 然后ViewModel具有一些默认值,在视图上直接呈现而已。定死的ViewModel,好像不是很常见,以至于你使用Visual Studio新建一个默认的Web应用程序的话,都看不到它。它就看起来像一个*.cshtml结尾的HTML文件,但是,cshtml文件却是服务端可以解析的一种文件,所以你可以在里面使用一些Razor语法,比如HtmlHelpers,UrlHelpers等。同样,你可以使用ViewBag或者ViewData来从Controller的Action传输数据到View里面,来让它具有动态的内容。但是ViewBagViewData都是弱类型的,所以没有智能提示,用起来略不爽。

要在你的视图中使用强类型数据对象,你需要定义一个Model来在视图中使用。

@model ExtendViews.ViewModels.AboutModel

<!-- usage: --->
@Model.FullName

这种方式是不是很常见的? 下一种方式是一个更好的方式来布局我们的视图:

#2:布局(Layouts):

相当于ASP.NET的WebForms的母版页,不过它是定义Razor视图的基本布局的一种方式。它就是_Layout.cshtml, 位于 Views\Shared\ 文件夹里 。通常情况下这个文件通常包含HTML的header,body和公用的一些东西。你可以多建几个互相进行组合,来完成整个站点的布局。其他页面引用布局视图页的时候,是这样子写的(注意不需要扩展名):

@{
Layout = "_Layout";
}

此调用需要在您的视图的第一行中。但你不需要在每一个视图中定义布局,如果你使用Visual Studio新建一个ASP.NET Core项目,Views文件夹有一个_ViewStart.cshtml,在运行的时候它会自动的导入到每个视图中去。

_Layout.cshtml有一个方法法叫 RenderBody(),它就是用来渲染详细的视图页到模板布局视图中:

@RenderBody()

在此方法的位置,详情视图就会被渲染到这里。

#3: 区域(Sections)

有时候子视图中想在主视图中显示一部分html代码,比如javascript代码或者是css,这个时候就可以使用Sections,通常情况下在页面的结尾部分。

在主视图中(_Layout.cshtml)定义一个Javascripts Section:


@RenderSection("scripts", required: false)

有一个required参数来声明这个Section是否必须的。然后你就可以在子视图中这样使用:

@section scripts
{
<script>
$(function() {
// some more js code here;
});
</script>
}

如果你使用嵌套的布局,你可能需要嵌套这个区域。意思就是你在Section里面嵌套调用RenderSection():

@section scripts
{
@RenderSection("scripts", required: false)
}

#4: 分部视图( PartialViews)

你可以提取html页面中重用的部分,把它放到一个新的Razor视图中,这个视图没有自己的Action,这种视图就叫做分部视图。 分部视图通常也在Views\Shard\文件夹。

分部视图同样也可以是一个数据视图,它可以从父视图中获取数据(但不是必须的):

@model IEnumerable<UserModel>
@if (Model.Any())
{
<ul>
@foreach (var user in Model)
{
<li>@user.FullName</li>
}
</ul>
}

这个分部视图需要从父视图中获取用户列表的数据

@{ await Html.RenderPartialAsync("Users", Model.Users);}

如果你的分部视图没有定义用户模型,你就不需要传第二个参数。

#5:视图组件(ViewComponents)

这个 ASP.NET Core特有的。

译者注:类似于以前的用户控件

有时候你需要做一些分部视图的事情,但是又包含一些业务逻辑在里面。在过去,你可以使用ChildAction渲染结果到一个视图中,但是,在 ASP.NET Core中,有一种新的方式来做这件事情,它就是ViewComponents(我已经写了一篇关于ViewComponents的博文)。它类似于在MVC中的一种迷你的MVC,也就是说他们可以有自己的Controller,和单个的action以及view。ViewComponents是完全独立于你的当前视图的,但是可以通过你当前的视图传输数据。

想这样调用它,来渲染一个ViewComponents:

@Component.Invoke("Top10Articles");

可以看我的博客来学习怎么创建自己的ViewComponent

请在我的预览后viewcomponent一看学习如何创建你自己的。

#6: HTML助手(HtmlHelpers)

HTMLHelper类中,你可以创建你自己的扩展方法来扩展Razor语法:

public static class HtmlHelperExtensions
{
public static HtmlString MyOwnHtmlHelper(this HtmlHelper helper, string message)
{
return new HtmlString($"<span>{message}<span>");
}
}

在你的视图中,创建一个可重用的部分是非常有用的,它比分部视图多包含了一些业务逻辑。比HTMLHelpers扩展更好的是新的TagHelpers,但是在扩展你视图的时候,HTMLHelpers仍然有它自己的一些适用的地方。

#7: 标签助手(TagHelper)

这是 ASP.NET Core 非常好的一个新特性。

一个扩展你视图的小助手,它看起来像一个原生的HTML标签一样。 在ASP.NET Core MVC中你应该使用 TagHelpers 来替换 HtmlHelpers,因为它们更加的简洁和容易使用。另一个巨大的好处就是依赖注入,在HtmlHelpers中是使用不了的,因为HtmlHelpers 扩展的都是静态内容。 但TagHelpers是一个公共类,我们可以很容易的在它的构造函数中注入服务。

下面是一个很简单的小示例,来展示怎么样定义一个TagHelper:

[TargetElement("hi")]
public class HelloTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "p";
output.Attributes.Add("id", context.UniqueId); output.PreContent.SetContent("Hello ");
output.PostContent.SetContent(string.Format(", time is now: {0}",
DateTime.Now.ToString("HH:mm")));
}
}

这里定义了一个叫做hi的标签,它以HTML标记来呈现,p标签的内容是当前时间。

使用:

<hi>John Smith</hi>

结果:

<p>Hello John Smith, time is now: 18:55</p>

ASP.NET Core MVC 已经默认提供了很多TagHelpers来替换以前的HtmlHelpers。例如ActionLink已经被新的TagHelper所替换:

@Html.ActionLink(“About me”, “About”, “Home”)

新的TagHelper像这样来创建一个link:

<a asp-controller=”Home” asp-action=”About”>About me</a>

以上两种方式来创建一个a标签的结果:

<a href=”/Home/About”>About me</a>

可以看到,TagHelpers看起来更像原生的HTML,他们在视图中更加的直观,更高的可读性,并且更容易使用。

#8: 依赖注入(Dependency Injection)

这也是ASP.NET Core的新特性。

在扩展你的视图的时候,可以使用依赖注入了,这是一个非常大改进。是的,你可以在你的视图中使用DI了。

在StackOverflow和reddit有人这样问?
这真的有意义吗? 这不是会搞乱我的视图吗? 这不是与MVC模式背离吗?

我认为,不是这样的。 的确,在真正需要的地方你才使用,并且,你使用的时候需要非常小心。 有这样一个有效的场景:你创建一个表单来编辑用户的资料信息(User Profile), 用户可以添加他的公司位置,地址, 国家城市等等,我不愿意从Action到View中传输公司位置 ,地址和国家城市。我只愿意通过用户资料本身(User Profile), 我只想在 Action 中处理用户资料(User Profile)。这时候可以注入服务来给我查询数据,这就是为什么这种情况下它是非常有用的。它可以让我们的Action和ViewModel 保持非常的干净。

Startup.cs中的ConfigureServices来注册你具体的服务,然后你就可以在视图中这样来使用,只需要一行代码:

@inject DiViews.Services.ICountryService CountryService;

现在你可以在你的视图中使用ContryService来填充国家下拉列表。

我在这篇博客中写了很多关于依赖注入的博文。

#9: 函数(Functions)

在一个ASP.NET MVC 项目中,我从来没有真正的使用过函数这个功能。我只在一个Umbraco的CMS系统中用过一次。不管怎么说,这也是扩展你视图的另一种小技巧。也许你有很复杂视图方面的业务逻辑,在这种情况下,你可以在你的视图中写C#方法:

@functions
{
public string ReverseString(string input)
{
return String.Join("", input.Reverse());
}
}

#10: 配置全局视图(Global view configuration)

最后一点,你可以在_ViewImports.cshtml文件中,来配置你其他视图中使用的一些比较公用的 using 引用,依赖注入等。

总结

不管是以前的MVC还是新的的Core的MVC, 都有很多方法来扩展视图,虽然扩展这些视图的方式有些类似,但是每一种都有它最适合的地方,所以我们在使用这些特性来解决我们的问题的时候,我们应该多加思考,找到最合适的方式。

NET Core 的 Views的更多相关文章

  1. [asp.net core]定义Tag Helpers

    原文地址 https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring Getting started wi ...

  2. [asp.net core] Tag Helpers 简介(转)

    原文地址 https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro What are Tag Helpers? ...

  3. ASP.NET Core - 关于标签帮助器您值得了解的五点

    如果您开发过ASP.NET Core Web应用程序,您应该已经熟悉了标签帮助器.ASP.NET Core应用程序依赖标签帮助器来呈现表单和表单字段是很常见的.所以,一个视图通常包含许多标签帮助器以及 ...

  4. ASP.NET Core Razor 视图组件

    视图组件简介 在新的ASP.NET Core MVC中,视图组件类似于局部视图,但它们更强大.视图组件不使用模型绑定,仅依赖于您在调用时提供的数据. 视图组件特性: 呈现页面响应的某一部分而不是整个响 ...

  5. 基础教程:视图中的ASP.NET Core 2.0 MVC依赖注入

    问题 如何在ASP.NET Core MVC Views中注入和使用服务. 解 更新 启动 类来为MVC添加服务和中间件. 添加一项服务 添加一个Controller,返回 ViewResult. 添 ...

  6. ASP.Net Core开发(踩坑)指南

    ASP.NET与ASP.NET Core很类似,但它们之间存在一些细微区别以及ASP.NET Core中新增特性的使用方法,在此之前也写过一篇简单的对比文章ASP.NET MVC应用迁移到ASP.NE ...

  7. ASP.NET Core 入门教程 7、ASP.NET Core MVC 分部视图入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC (Razor)分部视图简介 ASP.NET Core MVC (Razor)分部视图基础教程 ASP.NET Core MVC (Raz ...

  8. ASP.NET Core 入门教程 6、ASP.NET Core MVC 视图布局入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC (Razor)视图母版页教程 ASP.NET Core MVC (Razor)带有Section的视图母版页教程 ASP.NET Cor ...

  9. ASP.NET Core 入门教程 5、ASP.NET Core MVC 视图传值入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC 视图引擎(Razor)简介 ASP.NET Core MVC 视图(Razor)ViewData使用示例 ASP.NET Core MV ...

随机推荐

  1. xcode中控件共有属性

    Text,title 控件上的文字 backgroung 背景图片或颜色 alignment 布局(居中,..) mode显示模式(缩放,拉伸..) drawing 隐藏控件的可见性 alpha 透明 ...

  2. ARP网关占用

    30网段已经发生了2次ARP了 排查方法:我直去核心交换机直连镜像口,用wireshark抓包,过滤出ARP的包 发现的确有ARP的攻击,因为没有统计公司电脑和无线路由的MAC地址,所以只能一个个把无 ...

  3. C#4 for循环 迭代法 穷举法应用

    for()循环. 四要素: 初始条件,循环条件,状态改变,循环体. 执行过程: 初始条件--循环条件--循环体--状态改变--循环条件.... 注意:for的小括号里面分号隔开,for的小括号后不要加 ...

  4. Android onSaveInstanceState()

    我们知道,由于手机的内存问题,很容易造成切换activity之后上一个activity被回收的情况,虽然我们按下back按键的时候,还是能够回到上一个activity,但是此时我们并不是执行的onRe ...

  5. 关于PHPExcel

    在学PHPExcel的时候,在网上查了很多资料,花了很多时间,下面是我想要分享给大家的,我找到的并进行了一定修改的亲身实践成功的资料,希望大家对大家有所帮助. 首先,需要下载PhpExcel资料,下载 ...

  6. Delphi XE6 试用Android视频采集

    FMX支持视频采集,具体见FMX.Media,提供了很类支持音频.视频的处理. 按帮助文档,用Note3做了测试,结果,效率太低,不可用. 具体可查询帮助Video Capturing一节,我就是按这 ...

  7. WPF按钮清空自带样式,以及透明按钮时,Grid的Background属性设置引起"点击"问题.

    1.空样式按钮 <Style x:Key="EmptyButtonStyle" TargetType="Button">            &l ...

  8. docker 配置桥接网络

    2.5 docker配置桥接网络(上): 为了使本地网络中的机器和Docker 容器更方便的通信,我们经常会有将Docker容器 配置到和主机同一网段的需求. 这个需求其实很容器实现, 我们只需要将D ...

  9. static wechat red package tool

    ---------------------------------------------------------------------------------------------------- ...

  10. Spring、Spring事务详解;使用XML配置事务

    @Transactional可以设置以下参数: @Transactional(readOnly=false) // 指定事务是否只读的 true/false @Transactional(rollba ...