ASP.NET Core MVC 视图

简介: ASP.NET Core MVC中视图的知识和ASP.NET MVC有很多相似之处,学习难度较低。以下内容主要体现了编程中模块化的思想,模块化才应是我们关注的重点。Layout布局用于提供各个页面所需的公共部分,如:菜单、页头、页尾等。

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

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

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



<script src="~/js/lib/vue/vue.js"></script>


<script src="~/js/lib/vue/vue.min.js"></script>


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

@{

Layout="_Layout";

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

View Import & View Start
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.cshtml和ViewStart.cshtml文件直接位于Views文件夹下:

ViewImport&ViewStart_Default_Location.png
相比其它位置的其它位置ViewImports.cshtml和ViewStart.cshtml,直接位于Views文件夹中的ViewImports.cshtml和ViewStart.cshtml文件会优先执行
后执行的ViewImports.cshtml文件中的内容有可能会覆盖先执行ViewImports.cshtml文件中的内容
ViewImports.cshtml和ViewStart.cshtml文件的作用域是当前目录及子目录
Tag Helper
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

customer tag helper
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处理 @
customer tag helper

Partial View
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文件中的代码。其余与普通视图一样。

:warning:局部视图中定义的section只对当前局部视图可见

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

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

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

Partial Tag Helper

@ 局部视图文件后缀可以省略,如: @

@ 也可以使用局部视图文件全名,如: @

HTML Helper

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

@{

await Html.RenderPartialAsync("_PartialName");

}
相比于PartialAsync,RenderParatialAsync有着更好的性能。

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

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

渲染数据块而非整个响应

关注点分离、易于测试

可以有参数和业务逻辑

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

通常在层中调用

自定义视图组件
创建视图组件类:

视图组件继承自ViewComponent或使用ViewComponentAttribute特性
自定义类约定以ViewComponent结尾(非强制)
public class FirstViewComponent : ViewComponent
{

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

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

创建视图文件:

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

@Model


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

/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}
:ok: 推荐使用Default作为视图组件的视图文件名,且视图文件存放路径为:Views/Shared/Components/{View Component Name}/{View Name}

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

Component.InvokeAsync
Tag Helper
@addTagHelper *,Web

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


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



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

public IActionResult InvokeVC()
{

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

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

A view component defines its logic in an InvokeAsync method that returns a Task 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 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中的视图部分做了简要概述,相比于文中的各种概念,我们应该把注意力放到模块化设计上。模块化、抽象思维是程序员应该掌握的两种能力。他们可以让我们写出高内聚、低耦合的代码,

推荐阅读
Tag Helpers in ASP.NET Core

View components in ASP.NET Core

Areas in ASP.NET Core

目录
相关文章
|
1月前
|
存储 开发框架 JSON
ASP.NET Core OData 9 正式发布
【10月更文挑战第8天】Microsoft 在 2024 年 8 月 30 日宣布推出 ASP.NET Core OData 9,此版本与 .NET 8 的 OData 库保持一致,改进了数据编码以符合 OData 规范,并放弃了对旧版 .NET Framework 的支持,仅支持 .NET 8 及更高版本。新版本引入了更快的 JSON 编写器 `System.Text.UTF8JsonWriter`,优化了内存使用和序列化速度。
|
1月前
mcr.microsoft.com/dotnet/core/aspnet:2.1安装libgdiplus
mcr.microsoft.com/dotnet/core/aspnet:2.1安装libgdiplus
30 1
|
2月前
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
|
2月前
|
开发框架 .NET 中间件
ASP.NET Core Web 开发浅谈
本文介绍ASP.NET Core,一个轻量级、开源的跨平台框架,专为构建高性能Web应用设计。通过简单步骤,你将学会创建首个Web应用。文章还深入探讨了路由配置、依赖注入及安全性配置等常见问题,并提供了实用示例代码以助于理解与避免错误,帮助开发者更好地掌握ASP.NET Core的核心概念。
100 3
|
1月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
|
2月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
43 7
|
2月前
|
开发框架 NoSQL .NET
利用分布式锁在ASP.NET Core中实现防抖
【9月更文挑战第5天】在 ASP.NET Core 中,可通过分布式锁实现防抖功能,仅处理连续相同请求中的首个请求,其余请求返回 204 No Content,直至锁释放。具体步骤包括:安装分布式锁库如 `StackExchange.Redis`;创建分布式锁服务接口及其实现;构建防抖中间件;并在 `Startup.cs` 中注册相关服务和中间件。这一机制有效避免了短时间内重复操作的问题。
|
2月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
63 0
|
3月前
|
开发框架 监控 .NET
开发者的革新利器:ASP.NET Core实战指南,构建未来Web应用的高效之道
【8月更文挑战第28天】本文探讨了如何利用ASP.NET Core构建高效、可扩展的Web应用。ASP.NET Core是一个开源、跨平台的框架,具有依赖注入、配置管理等特性。文章详细介绍了项目结构规划、依赖注入配置、中间件使用及性能优化方法,并讨论了安全性、可扩展性以及容器化的重要性。通过这些技术要点,开发者能够快速构建出符合现代Web应用需求的应用程序。
58 0
|
3月前
|
开发框架 监控 .NET
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?