MVC是模型(Model)、视图(View)、控制器(Controller)的缩写,它是Web应用程序中一种常用的架构模式。这种模式将应用程序大体上分为3层,即Model层、View层和Controller层。它最主要的优点是实现了关注点分离(Separation of Concerns),将原本耦合在一起的3部分分离为独立的部分,这对开发、调试及测试应用程序都有极大的好处,如图3-5所示。

在ASP.NET Core MVC框架中,除了Controller、Model和Action外,它还包括路由、模型绑定、模型验证和过滤器等功能。

路由:

对于Web应用程序,路由是一个非常重要且基本的功能,它的主要功能是根据预先配置的路由信息对客户端传来的请求进行路由映射,映射完成后,再将请求传给对应的路由处理器处理。

对于ASP.NET Core MVC,定义路由的方法有以下两种。[插图] 基于约定的路由:基于约定的路由会根据一些约定来创建路由,它要在应用程序的Startup类中来定义,事实上,上面的示例就是基于约定的路由。[插图] 特性路由:使用C#特性对Controller和Action指定其路由信息。

一个应用程序可以定义多个路由,当它收到客户端的请求后,将会对每个定义的路由信息进行匹配,直到找到对应的路由。

另一种实现路由的方法是使用特性路由,即RouteAttribute。它能够为每个Controller,甚至每个Action显式地设置路由信息,只要在Controller类或Action方法上添加[Route]特性即可,因此它要更为灵活。

最后,需要说明的是,基本约定的路由与特性路由方式可以同时存在,但是如果已经为一个Action指定了特性路由,那么基本约定的路由在该Action上就不会起作用了。

模型绑定:

在ASP.NET Core MVC中,当一个HTTP请求通过其路由定位到Controller中的某一个Action上时,HTTP请求中的一部分信息会作为Action中的参数。正如在3.4.3节中所看到的,在URL中的id或name会传递给Action方法中的同名参数。将HTTP请求中的数据映射到Action中参数的过程称为模型绑定(Model Binding)。

除了从路由以及查询字符串中获取数据以外,ASP.NET Core MVC还会尝试从表单(Form)中获取数据来绑定到Action中的参数。因此,它主要使用以下3种数据源来为Action的参数提供数据,并且按照顺序来从以下每一种方式中获取。[插图] Form值:HTTP POST请求时表单中的数据。[插图] 路由值:通过路由系统解析得到。[插图] 查询字符串:从URL中的查询字符串中获取。

除了从路由以及查询字符串中获取数据以外,ASP.NET Core MVC还会尝试从表单(Form)中获取数据来绑定到Action中的参数。因此,它主要使用以下3种数据源来为Action的参数提供数据,并且按照顺序来从以下每一种方式中获取。[插图] Form值:HTTP POST请求时表单中的数据。[插图] 路由值:通过路由系统解析得到。[插图] 查询字符串:从URL中的查询字符串中获取。

模型验证:

模型验证是指数据被使用之前的验证过程,它发生在模型绑定之后。在ASP.NETCore MVC中,要实现对数据的验证,最方便的方式是使用数据注解(Dataannotation),它使用特性为数据添加额外的信息。数据注解通常用于验证,只要为类的属性添加需要的数据注解验证特性即可,这些特性均位于System.ComponentModel.DataAnnotations命名空间下。

通常情况下,这些验证特性已经能够满足常见的验证需求。然而,在特殊情况下,就需要使用复杂的、自定义的验证规则,ASP.NET Core MVC提供了两种创建自定义验证的方法,一种是创建新的特性,并使它继承自ValidationAttribute类;另一种是使待验证的Model实现IValidatableObject接口。

过滤器:

过滤器与中间件很相似,在ASP.NET Core MVC中,它们能够在某些功能前后执行,由此而形成一个管道。

ASP.NET Core MVC提供了以下5种类型的过滤器。

Authorization过滤器:最先执行,用于判断用户是否授权,如果未授权,则直接结束当前请求,这种类型的过滤器实现了IAsyncAuthorizationFilter或IAuthorizationFilter接口。

Resource过滤器:在Authorization过滤器后执行,并在执行其他过滤器(除Authorization过滤器外)之前和之后执行,由于它在Action之前执行,因而可以用来对请求判断,根据条件来决定是否继续执行Action,这种类型过滤器实现了IAsyncResourceFilter或IResourceFilter接口。

Action过滤器:在Action执行的前后执行,与Resource过滤器不一样,它在模型绑定后执行,这种类型的过滤器实现了IAsyncActionFilter或IActionFilter接口。

Exception过滤器:用于捕获异常,这种类型的过滤器实现了IAsyncExceptionFilter或IExceptionFilter接口。

Result过滤器:在IActionResult执行的前后执行,使用它能够控制Action的执行结果,比如格式化结果等。需要注意的是,它只有在Action方法成功执行完成后才会运行,这种类型过滤器实现了IAsyncResultFilter或IResultFilter接口。

当要创建过滤器时,应该实现IXXXFilter或IAsyncXXXFilter,这两个接口的区别是前者同步、后者异步。ASP.NET Core MVC会首先检查异步实现,如果没有实现异步方式,则继续检查同步实现,因此在创建过滤器时,不需要同步接口和异步接口都实现。以IAsyncActionFilter和IActionFilter为例,这两个接口的定义分别如下所示。

如果过滤器以全局有效的方式添加(即在Startup类的ConfigureServices方法中,通过调用AddMvc方法添加),则它会在ConfigureServices方法中被添加到容器中。而如果以特性的方式使用包含依赖项的过滤器时,则会出错,这是因为在自定义特性的构造函数中所定义的接口类型的参数并不是有效的特性参数。此时就需要使用[ServiceFilter]特性或[TypeFilter]特性,这两个特性都能够解决过滤器特性中引用其他依赖的问题。


欢迎关注个人公众号:

理解Asp.net MVC模式的更多相关文章

  1. [转载]深入理解ASP.NET MVC之ActionResult

    Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, actionNam ...

  2. 深入理解ASP.NET MVC(6)

    系列目录 Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, acti ...

  3. 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC

    系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...

  4. 深入理解ASP.NET MVC Day1

    深入理解ASP.NET MVC   ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.NET完全没有关系,是一个全新的Web开发,事实上 ...

  5. 七天学会ASP.NET MVC ——深入理解ASP.NET MVC

    七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC   系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二) ...

  6. 深入理解ASP.NET MVC(5)

    系列目录 回顾 系列的前4节深入剖析了ASP.NET URL路由机制,以及MVC在此基础上是如何实现Areas机制的,同时涉及到inbound和outbound很多细节部分.第2节中提到MvcRout ...

  7. 深入理解ASP.NET MVC(目录)

    学ASP.NET MVC2有一段时间了,也针对性的做了个练习.感觉这个框架还是不错的,所以决定要深入系统的学习一下.看到这样一本书: 作者博客:http://blog.stevensanderson. ...

  8. 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 【转】

    http://www.cnblogs.com/powertoolsteam/p/MVC_one.html 系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会A ...

  9. [转载] ASP.NET MVC (一)——深入理解ASP.NET MVC

    个人认为写得比较透彻得Asp.net mvc 文章,所以转载过来,原文链接在最后: ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.N ...

  10. 理解ASP.NET MVC的路由系统

    引言 路由,正如其名,是决定消息经由何处被传递到何处的过程.也正如网络设备路由器Router一样,ASP.NET MVC框架处理请求URL的方式,同样依赖于一张预定义的路由表.以该路由表为转发依据,请 ...

随机推荐

  1. dtd的三种引入方式

  2. SQLServer清空数据库日志

    -------SQl2008以上 清空日志-------- USE[master] GO ALTER DATABASE [数据库名称] SET RECOVERY SIMPLE WITH NO_WAIT ...

  3. 元数据管理平台对比预研 Atlas VS Datahub VS Openmetadata

    大家好,我是独孤风.元数据管理平台层出不穷,但目前主流的还是Atlas.Datahub.Openmetadata三家,那么我们该如何选择呢? 本文就带大家对比一下.要了解元数据管理平台,先要从架构说起 ...

  4. 新版的Django中的path不能使用正则表达式

    新版的path 虽然 取代了 之前的url,但是在写路由的时候不能在路由中直接写正则表达式,不然会找不到页面. 解决方法使用 re_path from django.urls import re_pa ...

  5. 我用 Laf 开发了一个非常好用的密码管理工具

    [KeePass 密码管理]是一款简单.安全简洁的账号密码管理工具,服务端使用 Laf 云开发,支持指纹验证.FaceID,N 重安全保障,可以随时随地记录我的账号和密码. 写这个小程序之前,在国内市 ...

  6. 重磅!KubeEdge单集群突破10万边缘节点|云原生边缘计算峰会前瞻

    摘要:<KubeEdge单集群突破10万边缘节点 | 技术报告>将会在6月25日即将开展的云原生边缘计算峰会(KubeEdge Summit 2022)中进行应用解析.我们先来一睹为快吧! ...

  7. 【开源项目推荐】——纯中文本地GPT知识库搭建项目.assets

    大家好,我是独孤风. 又到了本周的开源项目推荐.近一年多的时间,人工智能迎来了大爆发.GPT相关的大模型的发展让很多领域都发生了巨大的变化. 但是虽然GPT的自然语言识别功能异常的强大,但回答给我们的 ...

  8. 使用 Python 参与算法竞赛

    引言 众所周知,打算法竞赛最频繁使用的语言是 C++.然而,对于那些不卡复杂度的题目,可以考虑使用 Python 编写(因为 Python 真的好写). 本文将简单地介绍一些 Python 使用技巧和 ...

  9. [计数dp] 整数划分(模板题+计数dp+完全背包变种题)

    计数类 dp 可分为 计数 dp 和数位统计 dp.大多是用来统计方案数什么的,特别强调 不重不漏,在此还是根据各个题的特点将计数 dp 和数位 dp 分开整理.其实数位 dp 的题目会相对多很多- ...

  10. 将Sublime Text打造为轻量级的C++ IDE

    本文较为详细地介绍了在Windows系统下,如何配置Sublime Text的C++编译运行环境.目前实现了了可以在Sublime Text按下快捷键后,调出CMD或者终端来运行C/C++程序,从而解 ...