🌐04 ASP.NET Core 入门
00 分钟
2023-12-19
2023-12-20
type
status
date
slug
summary
tags
category
icon
password

ASP.NET Core MVC概念

模型(Model)、视图(View)和控制器(Controller) 老师是控制器,成绩单是模型,你爸是视图。
项目结构:
  • 1、控制器由Controller类实现,视图一般是扩展名为cshtml的文件,而模型则是只有属性的普通C#类。
  • 2、控制器类的名字一般以Controller结尾,并且被放到Controllers文件夹下。控制器的名字为控制器的类名去掉Controller。
  • 3、视图一般被放到Views文件夹下的控制器名字的文件夹下。
  • 4、视图→浏览器端提交的请求→模型→控制器→处理→模型→视图。渲染:Render。
Hot Reload 热加载
1、困惑:修改了服务器端的代码,必须重新运行程序。 2、方法1:【启动(不调试)】 3、方法2:.NET 6开始的Hot Reload(热重载)
缺点:删除了方法或者修改了参数,热重载就可能无法正常执行

ASP.NET Core WebAPI入门

1、什么是结构化的Http接口。Json。 2、Web API项目的搭建。 3、Web API项目没有Views文件夹。 4、运行项目,解读代码结构。 5、【启用OpenAPI支持】→swagger,在界面上进行接口的测试。

REST风格

  • 1、Web API两种风格:面向过程(RPC)、面向REST(REST)
  • 2、RPC:“控制器/操作方法“的形式把服务器端的代码当成方法去调用。把HTTP当成传输数据的通道,不关心HTTP谓词。通过QueryString、请求报文体给服务器传递数据。状态码。比如:/Persons/GetAll、/Persons/GetById?id=8、/Persons/Update、/Persons/DeleteById/8;
  • REST:按照HTTP的语义来使用HTTP协议:
    • 1、URL用于资源的定位:/user/888、/user/888/orders;
      2、HTTP谓词:GET、POST(新增)、PUT(整体更新)、DELETE、PATCH(局部更新)等;
      3、什么是“幂等”,举例?DELETE、PUT、GET是幂等的,POST不幂等;
      4、GET的响应可以被缓存;
      5、服务器端要通过状态码来反映资源获取的结果:404、403(没有权限)、201(新增成功)。
RPC:业务驱动,自然。
REST:要求开发人员对REST原则更了解、并且有更多的设计能力。
HTTP传递参数的三种方式
URL:适合定位;长度限制。
QueryString:灵活;长度限制。
请求报文体:灵活;长度不限制;不支持GET、Delete。
URL:资源定位。
QueryString:URL之外的额外数据。
请求报文体:供PUT、POST提供数据。
1、完全按照HTTP语义要求高。
2、
1)对于保存、更新类的请求POST、PUT请求,把全部参数都放到请求报文体中;
2)对于DELETE请求,要传递的参数就是一个资源的id,因此把参数放到QueryString中即可;
3)对于GET请求,一般参数的内容都不会太长,因此统一通过QueryString传递参数就可以。对于极少数参数内容超过URL限制的请求,由于GET、PUT请求都是幂等的,因此我们把请求改成通过PUT请求,然后通过报文体来传递参数。
1、控制器上 [Route("[controller]/[action]")]
2、强制要求控制器中不同的操作用不同的方法名
3、把[HttpGet]、[HttpPost]、[HttpDelete]、[HttpPut]等添加到对应的操作方法上。
注意:如果控制器中存在一个没有添加[HttpGet]、[HttpPost]等的public方法,Swagger就会报错,可以用[ApiExplorerSettings(IgnoreApi = true)]

Action方法的异步

Action方法的参数

捕捉URL占位符
  • 1、在[HttpGet]、[HttpPost]等中使用占位符,比如{schoolName},捕捉路径中的内容,从而供Action方法的参数使用。 /Students/GetAll/school/MIT/class/A001 [HttpGet("school/{schoolName}/class/{classNo}")]
  • 2、捕捉的值会被自动赋值给Action中同名的参数;如果名字不一致,可以用[FromRoute(Name="名字")]
捕捉QueryString的值
  • 1、使用[FromQuery]来获取QueryString中的值。如果名字一致,只要为参数添加[FromQuery]即可;而如果名字不一致,[FromQuery(Name = 名字)]。
  • 2、QueryString和Route可以混用。演示。
Json报文体
  • 1、Web API的开发模式下,Json格式的请求体是主流。
  • 2、只要声明一个模型类和Json请求的格式一致即可。
  • 3、也是可以把从URL获取参数、从请求报文体获取数据等这些混合使用。 [HttpPost("classId/{classId}")] public ActionResult<long> AddNew(long classId, StudentModel s)
  • 4、一定要设定请求头中的Content-Type为application/json,而且数据必须是合法的json格式。
Web API中很少用的方式:
1、从Content-Type为multipart/form-data的请求中获取数据的[FromForm]
2、从请求报文头中获取值的[FromHeader]。

前后端分离开发

  • 1、传统MVC开发模式:前后端的代码被放到同一个项目中,前端人员负责编写页面的模板,而后端开发人员负责编写控制器和模型的代码并且“套模板”。缺点:互相依赖;耦合性强;责任划分不清。
  • 2、主流的“前后端分离” :前端开发人员和后端开发人员分别负责前端和后端代码的开发,各自在自己的项目中进行开发;后端人员只写Web API接口,页面由前端人员负责。 为什么“前后端分离” 更流行:需求变动越来越大、交付周期越来越短、多端支持。。 优点:独立开发,不互相依赖;耦合性低;责任划分清晰;前后端分别部署,可以针对性运维(扩容等) 缺点:对团队的沟通能力要求更高,提前沟通好接口和通知接口变更;不利于SEO(可以用“服务器端渲染”SSR);对运维要求更高。

ASP.NET Core中依赖注入的使用

1、在ASP.NET Core项目中一般不需要自己创建ServiceCollection、IServiceProvider。在Program.cs的builder.Build()之前向builder.Services中注入。 2、在Controller中可以通过构造方法注入服务。
低使用频率的服务
1、把Action用到的服务通过Action的参数注入,在这个参数上标注[FromServices]。和Action的其他参数不冲突。 2、一般不需要,只有调用频率不高并且资源的创建比较消耗资源的服务才[FromServices]。 3、只有Action方法才能用[FromServices] ,普通的类默认不支持。

案例:开发模块化的服务注册框架

框架的使用

ASP.NET Core客户端响应缓存——浏览器缓存

cache-control

ASP.NET Core服务器端响应缓存

Response Caching Middleware
服务器端响应缓存很鸡肋
1、无法解决恶意请求给服务器带来的压力。
2、服务器端响应缓存还有很多限制,包括但不限于:响应状态码为200的GET或者HEAD响应才可能被缓存;报文头中不能含有Authorization、Set-Cookie等。
3、不怪他,honor RFC7234. It’s a feature, not a bug.
4、怎么办?采用内存缓存、分布式缓存等。

ASP.NET Core中的内存缓存

内存缓存(In-memory cache)

缓存的过期时间策略

缓存的过期时间
缓存的绝对过期时间
缓存的滑动过期时间
两种过期时间混用

缓存穿透问题

什么是缓存穿透
缓存穿透的解决方案

缓存雪崩和数据混乱问题

缓存雪崩
1、缓存项集中过期引起缓存雪崩。
2、解决方法:在基础过期时间之上,再加一个随机的过期时间。
缓存数据混乱

封装内存缓存操作的帮助类

需求

ASP.NETCore与配置系统的集成

ASP.NET Core默认添加的配置提供者
1)加载现有的IConfiguration。
2)加载项目根目录下的appsettings.json。
3)加载项目根目录下的appsettings.{Environment}.json。
4)当程序运行在开发环境下,程序会加载“用户机密”配置。
5)加载环境变量中的配置。
6)加载命令行中的配置。

.NET Core防止机密配置外泄

1、把不方便放到appsettings.json中的机密信息放到一个不在项目中的json文件中。
2、在ASP.NET Core项目上单击鼠标右键,选择【管理用户机密】。
3、secrets.json文件到底保存在哪里?如何和项目建立关系?csproj文件中的<UserSecretsId>

ASP.NET Core异常Filter

什么是Filter
1、切面编程机制,在ASP.NET Core特定的位置执行我们自定义的代码。
2、ASP.NET Core中的Filter的五种类型:
  • Authorization filter、 授权过滤器
  • Resource filter、 资源过滤器
  • Action filter、 控制器过滤器
  • Exception filter、 异常过滤器
  • Result filter。 结果过滤器
    • 重点讲解Exception filter和Action filter。 Exception filter 是处理的异常的
      Action filter 分为控制器方法执行前执行和执行后执行
3、所有筛选器一般有同步和异步两个版本,比如IActionFilter、IAsyncActionFilter接口。
Exception filter的使用
Action filter的使用
1、Action Filter可以在满足条件的时候终止操作方法的执行。
2、在Action Filter中,如果我们不调用await next(),就可以终止Action方法的执行了。
3、为了避免恶意客户端频繁发送大量请求消耗服务器资源,我们要实现“一秒钟内只允许最多有一个来自同一个IP地址的请求”。

自动启用事务的筛选器

1、数据库事务:要么全部成功、要么全部失败。
2、自动化:启动、提交以及回滚事务。
3、当一段使用EF Core进行数据库操作的代码放到TransactionScope声明的范围中的时候,这段代码就会自动被标记为“支持事务”。
4、TransactionScope实现了IDisposable接口,如果一个TransactionScope的对象没有调用Complete()就执行了Dispose()方法,则事务会被回滚,否则事务就会被提交。
5、TransactionScope还支持嵌套式事务。
6、.NET Core中的TransactionScope不像.NET FX一样有MSDTC分布式事务提升的问题。请使用最终一致性事务。
原始的事务控制器
自动启用

ASP.NET Core 中间件

中间件是ASP.NET Core的核心组件,MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。
什么是中间件
1、广义上来讲:Tomcat、WebLogic、Redis、IIS;狭义上来讲,ASP.NET Core中的中间件指ASP.NET Core中的一个组件。
2、中间件由前逻辑、next、后逻辑3部分组成,前逻辑为第一段要执行的逻辑代码、next为指向下一个中间件的调用、后逻辑为从下一个中间件执行返回所执行的逻辑代码。
每个HTTP请求都要经历一系列中间件的处理,每个中间件对于请求进行特定的处理后,再转到下一个中间件,最终的业务逻辑代码执行完成后,响应的内容也会按照处理的相反顺序进行处理,然后形成HTTP响应报文返回给客户端。
3、中间件组成一个管道,整个ASP.NET Core的执行过程就是HTTP请求和响应按照中间件组装的顺序在中间件之间流转的过程。开发人员可以对组成管道的中间件按照需要进行自由组合。
中间件的三个概念
Map、Use和Run。Map用来定义一个管道可以处理哪些请求,Use和Run用来定义管道,一个管道由若干个Use和一个Run组成,每个Use引入一个中间件,而Run是用来执行最终的核心应用逻辑。
简单的自定义中间件
1、如果中间件的代码比较复杂,或者我们需要重复使用一个中间件的话,我们最好把中间件的代码放到一个单独的“中间件类”中。
2、中间件类是一个普通的.NET类,它不需要继承任何父类或者实现任何接口,但是这个类需要有一个构造方法,构造方法至少要有一个RequestDelegate类型的参数,这个参数用来指向下一个中间件。
这个类还需要定义一个名字为Invoke或InvokeAsync的方法,方法至少有一个HttpContext类型的参数,方法的返回值必须是Task类型。中间件类的构造方法和Invoke(或InvokeAsync)方法还可以定义其他参数,其他参数的值会通过依赖注入自动赋值。

Filter与Middleware的区别

关系:
中间件是ASP.NET Core这个基础提供的功能,而Filter是ASP.NET Core MVC中提供的功能。ASP.NET Core MVC是由MVC中间件提供的框架,而Filter属于MVC中间件提供的功能。
区别:
1、中间件可以处理所有的请求,而Filter只能处理对控制器的请求;中间件运行在一个更底层、更抽象的级别,因此在中间件中无法处理MVC中间件特有的概念。
2、中间件和Filter可以完成很多相似的功能。“未处理异常中间件”和“未处理异常Filter”;“请求限流中间件”和“请求限流Filter”的区别。
3、优先选择使用中间件;但是如果这个组件只针对MVC或者需要调用一些MVC相关的类的时候,我们就只能选择Filter。