ASP.NET Core MVC 视图

ASP.NET Core MVC中视图的知识和ASP.NET MVC有很多相似之处,学习难度较低。以下内容主要体现了编程中模块化的思想,模块化才应是我们关注的重点。

布局用于提供各个页面所需的公共部分,如:菜单、页头、页尾等。在ASP.NET Core中默认的布局文件是位于/Views/Shared文件夹下的_Layout.cshtml文件:

640?wx_fmt=png

我们通常在_Layout.cshtml中引入公共资源,如:

<link href="~/css/reset.css" rel="stylesheet" />
<link href="~/css/index.css" rel="stylesheet" /><script src="~/js/common/net/ajaxHandler.js"></script>
<environment names="Development">
<script src="~/js/lib/vue/vue.js"></script>
</environment>
<environment names="Production">
<script src="~/js/lib/vue/vue.min.js"></script>
</environment>

指定布局文件

可以在Razor视图(即,cshtml文件)中使用Layout属性来指定使用哪个布局文件:

ASP.NET Core MVC搜索布局文件的方式与局部视图一样,下文中会详细说明。默认情况下,在布局文件中必须调用RenderBody方法。还可以使用RenderSection方法来引入section

View Import

可以在_ViewImport.cshtm文件中添加命名空间或者Tag Helper以供其它视图中使用,如:

@using Microsoft.AspNetCore.Identity
@addTagHelper
*, Microsoft.AspNetCore.Mvc.TagHelpers

_ViewImport.cshtm文件可以使用以下指令:

  • @addTagHelper

  • @removeTagHelper

  • @tagHelperPrefix

  • @using

  • @model

  • @inherits

  • @inject

_ViewImport.cshtm文件不支持Razor文件的其它特性,如:function、section等。对于多个_ViewImports.cshtml的情况,指令运行结果遵循如下规则:

  • @addTagHelper@removeTagHelper: 按照先后顺序执行

  • @tagHelperPrefix: 后执行的结果覆盖先执行的结果

  • @model: 后执行的结果覆盖先执行的结果

  • @inherits: 后执行的结果覆盖先执行的结果

  • @using: 引入所指定的所有命名空间,但忽略重复引用

  • @inject: 后注入覆盖先注入的同名属性

View Start

_ViewStart.cshtml文件中的代码会在所有完整视图(full view,not layout,not partial view)文件被渲染之前执行。

默认情况下,ViewImports.cshtmlViewStart.cshtml文件直接位于Views文件夹下:

640?wx_fmt=png

  • 相比其它位置的其它位置ViewImports.cshtmlViewStart.cshtml,直接位于Views文件夹中的ViewImports.cshtmlViewStart.cshtml文件会优先执行

  • 后执行的ViewImports.cshtml文件中的内容有可能会覆盖先执行ViewImports.cshtml文件中的内容

  • ViewImports.cshtmlViewStart.cshtml文件的作用域是当前目录及子目录

Tag Helper可以让服务器端代码参与到在Razor文件中创建和渲染HTML元素的工作中。

自定义Tag Helper:

public class XfhTagHelper : TagHelper
{
public string Content { set; get; }

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
output.TagName
= "a";
output.Attributes.Add(
"href", "https://www.google.com");
output.Content.SetContent(Content);
}
}

使用Tag Helper:

@addTagHelper *,Web

<xfh content="haha">customer tag helper</xfh>

Tag Helper与HTML Helper有些相似,二者不同之处可参考:Tag Helpers compared to HTML Helpers

Tag Helper具有以下优点:

  • 类HTML语法

    这一点是我喜欢Tag Helper的原因,使用Tag Helper可以使cshtml文件中后台代码与前端的搭配更和谐,利于提升代码可读性

  • 语法智能感知

Tag Helper 作用域

  • @addTagHelper

    @addTagHelper的第一个参数表示要加载哪些Tag Helper,使用"*"表示加载所有的Tag Helper;第二个参数表示从哪个程序集中加载Tag Helper。示例如下:

    @* 需指明TagHelper的完全限定名 *@
    @addTagHelper Web.TagHelpers.XfhTagHelper,Web
  • @removeTagHelper

    @removeTagHelper也有两个参数,含义同@addTagHelper

  • @tagHelperPrefix

    给Tag Helper加上前缀标识,示例如下:

    @addTagHelper *,Web
    @tagHelperPrefix th:

    @* 不会被当作Tag Helper处理 *@
    <xfh content="haha">customer tag helper</xfh>
    <th:xfh content="tagHelperPrefix"></th:xfh>

Partial view,局部视图是一个Razor文件,它通常嵌套在另一个Razor文件中。局部视图主要用于拆分大的Razor文件及代码复用。但请注意:

  • 局部视图不应用来维护公共布局中的内容,考虑使用_Layout.cshtml来维护公共布局

    Partial views shouldn't be used to maintain common layout elements.

  • 尽量不要在局部视图中使用复杂的渲染逻辑,或者需要执行一些代码片段才能获取到视图元素。这种情况考虑使用view component来替代局部视图。

    Don't use a partial view where complex rendering logic or code execution is required to render the markup.If you need to execute code, use a view component instead of a partial view.

声明局部视图

局部视图名通常以下划线_开头,下划线主要用于易于辨识局部视图文件。注意一点,在渲染局部视图时,不会执行_ViewStart.cshtml文件中的代码。其余与普通视图一样。

⚠️局部视图中定义的section只对当前局部视图可见

使用局部视图

引用局部视图文件而不带扩展名cshtml时,在MVC框架中,会从以下路径中加载局部视图文件,优先级从上而下依次降低:

  1. /Areas/<Area-Name>/Views/<Controller-Name>

  2. /Areas/<Area-Name>/Views/Shared

  3. /Views/Shared

  4. /Pages/Shared

当引用局部文件带上扩展名时,局部视图文件必须和引用方位于相同目录下。

可使用以下方式引入局部视图:

  • Partial Tag Helper

  <partial name="partial.cshtml" model="Model"/>
@* 局部视图文件后缀可以省略,如: *@
<partial name="partial" />
@* 也可以使用局部视图文件全名,如: *@
<partial name="~/Views/Shared/_PartialName.cshtml" />
  • HTML Helper

    @await Html.PartialAsync("_PartialName")

也可以使用 RenderPartialAsync方法来渲染局部视图,该方法直接将渲染结果写入到response中,而不是返回 IHtmlContent,所以只能在Razor代码块中调用该方法:

@{
await Html.RenderPartialAsync("_PartialName");
}

相比于PartialAsyncRenderParatialAsync有着更好的性能。

View component,视图组件和局部视图类似,但它更强大。一个视图组件包含两部分:ViewComponent类和一个视图。

视图组件不使用模型绑定,视图组件中所用的数据有调用者提供。视图组件有以下特点:

  • 渲染数据块而非整个响应

  • 关注点分离、易于测试

  • 可以有参数和业务逻辑

    MVC本身就提倡关注点分离,所以,视图组件中应尽可能只包含与渲染视图相关的逻辑

  • 通常在层中调用

自定义视图组件

创建视图组件类:

  • 视图组件继承自ViewComponent或使用ViewComponentAttribute特性

  • 自定义类约定以ViewComponent结尾(非强制)

public class FirstViewComponent : ViewComponent
{
// 方法名InvokeAsync是基于约定的,同步方法名为Invoke
public async Task<IViewComponentResult> InvokeAsync(string descript)
{
return View<string>(descript);
}
}

⚠️ 视图组件类中可以使用依赖注入。需注意:视图组件不会参与到Controller的生命周期中,所以filter对它无效。

创建视图文件:

视图组件默认视图名为:Default,简单定义视图内容如下:

在运行时按照以下顺序搜索视图文件:

  • /Views/{Controller Name}/Components/{View Component Name}/{View Name}

  • /Views/Shared/Components/{View Component Name}/{View Name}

  • /Pages/Shared/Components/{View Component Name}/{View Name}

? 推荐使用Default作为视图组件的视图文件名,且视图文件存放路径为:Views/Shared/Components/{View Component Name}/{View Name}

可以使用如下两种方式来调用视图组件:

  • Component.InvokeAsync

  • Tag Helper

@addTagHelper *,Web

<div class="text-center">
@await Component.InvokeAsync("First", new { descript = "invoking view component" })
<br />
@* Tag Helper方式调用ViewComponent,需以vc:作为前缀 *@
<vc:first descript="tag helper">
</vc:first>
</div>

⚠️ 注意,使用Tag Helper形式调用视图组件时,组件名和组件的方法参数使用 kebab case方式,即,组件PriorityList有参数maxPriority,则调用方式如下:

<vc:priority-list max-priority="2">
</vc:priority-list>

除此之外,还可以在Controller中调用视图组件:

public IActionResult InvokeVC()
{
// 注意,视图组件名称大小写敏感
return ViewComponent("First", new { Descript = "controller"});
}

View component methods

抄录一段微软官网上对于View component methods的总结,人太懒,就不翻译了?,留意加粗部分:

A view component defines its logic in an InvokeAsync method that returns a Task<IViewComponentResult> or in a synchronous Invoke method that returns an IViewComponentResult. Parameters come directly from invocation of the view component, not from model binding. A view component never directly handles a request. Typically, a view component initializes a model and passes it to a view by calling the View method. In summary, view component methods:

  • Define an InvokeAsync method that returns a Task<IViewComponentResult> or a synchronous Invokemethod that returns an IViewComponentResult.

  • Typically initializes a model and passes it to a view by calling the ViewComponent View method.

  • Parameters come from the calling method, not HTTP. There's no model binding.

  • Are not reachable directly as an HTTP endpoint. They're invoked from your code (usually in a view). A view component never handles a request.

  • Are overloaded on the signature rather than any details from the current HTTP request.

本文主要对ASP.NET Core中的视图部分做了简要概述,相比于文中的各种概念,我们应该把注意力放到模块化设计上。模块化、抽象思维是程序员应该掌握的两种能力。他们可以让我们写出高内聚、低耦合的代码。

原文地址:https://www.cnblogs.com/Cwj-XFH/p/10885745.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 
640?wx_fmt=jpeg


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

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

相关文章

CF993E Nikita and Order Statistics

CF993E Nikita and Order Statistics 题意&#xff1a; 给你一个数组 a1∼na_{1 \sim n}a1∼n​&#xff0c;对于 k0∼nk 0 \sim nk0∼n&#xff0c;求出有多少个数组上的区间满足&#xff1a;区间内恰好有 k 个数比 x 小。 x 为一个给定的数。 n≤2105n \le 2 \times 10^5n…

ASP.NET Core 通过 Microsoft.DotNet.Watcher.Tools 实现热部署

之前开发前端的时候&#xff0c;webpack 会有热更新工具&#xff0c;在修改了代码之后&#xff0c;自动将代码编译&#xff0c;实时展现到页面上&#xff0c;给开发带来了极大的方便。Java也可以通过第三方插件JRebel实现热部署&#xff0c;不用频繁的重启Tomcat。微软官方也为…

P3825 [NOI2017]游戏

P3825 [NOI2017]游戏 题目描述 小 L 计划进行n场游戏&#xff0c;每场游戏使用一张地图&#xff0c;小 L 会选择一辆车在该地图上完成游戏。 小 L 的赛车有三辆&#xff0c;分别用大写字母A、B、C表示。地图一共有四种&#xff0c;分别用小写字母x、a、b、c表示。其中&#x…

事关SuperSocket发布,寻找YangFan哥哥

SuperSocket近日发布了2.0的第一个预览版《SuperSocket 2.0 Preview1 发布&#xff0c;.NET Socket服务器框架》&#xff0c;在NuGet上以一个包含数个SuperSocket程序集的大包的形式发布。https://www.nuget.org/packages/SuperSocket/2.0.0-preview1我原意以独立小包的形式发布…

P3321 [SDOI2015]序列统计(未解决)

P3321 [SDOI2015]序列统计 题意&#xff1a; 题解&#xff1a; 参考题解&#xff1a; 题解 P3321 【[SDOI2015]序列统计】 【LG3321】[SDOI2015]序列统计 神仙题。。学透再补 代码&#xff1a;

P1963 [NOI2009]变换序列

题目描述 不想水字&#xff0c;详见某谷&#xff1a;P1963 [NOI2009]变换序列 solution 其实 的计算就类似于环上的距离。 对于每一个 都可能有两种位置选择&#xff1a;&#xff0c; 。 所以把它们分别连边&#xff0c;二分图上匈牙利算法求完美匹配即可。 #include&…

一次 .NET Core 中玩锁的经历:ManualResetEventSlim, SemaphoreSlim

最近同事对 .net core memcached 缓存客户端 EnyimMemcachedCore 进行了高并发下的压力测试&#xff0c;发现在 linux 上高并发下使用 async 异步方法读取缓存数据会出现大量失败的情况&#xff0c;比如在一次测试中&#xff0c;100万次读取缓存&#xff0c;只有12次成功&…

BZOJ4589. Hard Nim

BZOJ4589. Hard Nim 题意&#xff1a; Claris和NanoApe在玩石子游戏&#xff0c;他们有n堆石子&#xff0c;规则如下&#xff1a; Claris和NanoApe两个人轮流拿石子&#xff0c;Claris先拿。每次只能从一堆中取若干个&#xff0c;可将一堆全取走&#xff0c;但不可不取&…

P2825 [HEOI2016/TJOI2016]游戏

题目描述 详见 P2825 [HEOI2016/TJOI2016]游戏。 solution 套路题。 一般思路是行列建点跑二分图最大匹配。 此题中的#会分隔行列&#xff0c;因此我们把每行的极大联通块设为点&#xff0c;列同理建点。 再对于每个*对应的行的极大联通块与列的最大联通块编号连边&…

P3033 [USACO11NOV]牛的障碍Cow Steeplechase

P3033 [USACO11NOV]牛的障碍Cow Steeplechase 题目描述 详见&#xff1a;P3033 [USACO11NOV]牛的障碍Cow Steeplechase solution 裸题。 对于每一对相交的线段&#xff0c;连一条边&#xff0c;表示这一对线段不能都取。 显然这样会建立一个二分图&#xff08;横的线段不…

Tree Cutting HDU - 5909

Tree Cutting HDU - 5909 题意&#xff1a; 一个无根树&#xff0c;n个点&#xff0c;n-1条边&#xff0c;每个节点有一个权值&#xff0c;一棵树的权值就是其节点(包含本身及其子节点)的权值的异或和&#xff1b;求价值为[0,m)的树有多少颗&#xff1f;(所谓的树其实就是原连…

Redis作者antirez:开源维护者的挣扎

这两天&#xff0c;一篇名为《开源维护者的挣扎》的文章被迅速顶至 Hacker News 首页&#xff0c;这是 Redis 作者 antirez 发布的最新博客。几个月前&#xff0c;一名开源项目的维护者向 antirez 发邮件&#xff0c;倾诉自己苦心维护项目多年&#xff0c;这或多或少带来了一些…

CF662C Binary Table

CF662C Binary Table 题意&#xff1a; 有一个 n 行 m 列的表格&#xff0c;每个元素都是 0/1 &#xff0c;每次操作可以选择一行或一列&#xff0c;把 0/1 翻转&#xff0c;即把 0 换为 1 &#xff0c;把 1 换为 0 。请问经过若干次操作后&#xff0c;表格中最少有多少个 1 …

P4111 [HEOI2015]小Z的房间

P4111 [HEOI2015]小Z的房间 题目描述 详见&#xff1a;P4111 [HEOI2015]小Z的房间 solution Matrix-Tree裸题。 题意为求一个有障碍的网格图的生成树个数。 因此对于每一个点向左边和上面的节点连边&#xff0c;Matrix-Tree定理求解生成树个数即可。 #include<bits/s…

黑科技抢先尝(续) - Windows terminal中WSL Linux 终端的极简美化指南

之前&#xff0c;本人写了两篇文章 黑科技抢先尝 | Windows全新终端初体验(附代码Build全过程) 和 程会玩 | 无需自行编译也能玩转 Windows Terminal&#xff0c;介绍了玩转Windows terminal的两种方式。今天这篇文章&#xff0c;主要介绍如何美化 Windows terminal 中 WSL 的 …

P3203 [HNOI2010]弹飞绵羊

P3203 [HNOI2010]弹飞绵羊 题目描述 详见&#xff1a;P3203 [HNOI2010]弹飞绵羊 solution 这是一道LCT的裸题。 但是我并不想用LCT解决此题&#xff08;In fact 是不会LCT ~QAQ&#xff09; 于是我们开始大力分块。 考虑把弹跳装置分块&#xff0c;我们每次需要知道在一…

L - Two Ants Gym - 102823L

L - Two Ants Gym - 102823L 题意&#xff1a; 有两个线段A&#xff0c;B&#xff0c;两个线段不会超过一个公共点&#xff0c; 你站在线段B上&#xff0c;整个平面你看不到的区域的面积(如图中S所在区域) 题解&#xff1a; 计算几何&#xff0c;恶心题。调了一个小时还是…

C# 8.0 中开启默认接口实现

当你升级到 C# 8.0 和 .NET Core 3.0 之后&#xff0c;你就可以开始使用默认接口实现的功能了。从现在开始&#xff0c;你可以在接口里面添加一些默认实现的成员&#xff0c;避免在接口中添加成员导致大量对此接口的实现崩溃。要写出并且正常使用接口的默认实现&#xff0c;你需…

P4396 [AHOI2013]作业

P4396 [AHOI2013]作业 题目描述 详见&#xff1a;P4396 [AHOI2013]作业 solution 莫队树状数组的裸题&#xff08;莫队分块&#xff0c;CDQ分治都可以&#xff0c;莫队线段树大概需要卡常&#xff09;。 时间复杂度 Code #include<bits/stdc.h> using namespac…

Codeforces Round #732 (Div. 1Div. 2)

Codeforces Round #732 (Div. 2) 题号题目知识点AAquaMoon and Two Arrays贪心BAquaMoon and Stolen String异或CAquaMoon and Strange SortDAquaMoon and ChessEAquaMoon and PermutationsFAquaMoon and Wrong CoordinateG1AquaMoon and Time Stop (easy version)G2AquaMoon …