概述:
ASP.NET Core是一个跨平台的开源Web应用程序框架,用于构建现代化、高性能和可扩展的Web应用程序。它是微软公司推出的下一代ASP.NET框架,具有许多改进和新功能。
以下是ASP.NET Core的一些主要特点和优势:
- 跨平台支持:ASP.NET Core可以在Windows、Linux和macOS等多个操作系统上运行,使开发人员能够选择他们喜欢的开发环境。
- 高性能:ASP.NET Core采用了一些性能优化措施,如内置的请求管道、异步编程模型和轻量级的HTTP处理器,以提供卓越的性能和吞吐量。
- 简化的开发流程:ASP.NET Core引入了一种模块化和轻量级的开发模式,使开发人员能够更快速地构建应用程序。它支持依赖注入、中间件管道和统一的配置模型等特性,简化了开发流程。
- 支持云原生应用程序:ASP.NET Core与云平台紧密集成,支持容器化部署和微服务架构。它提供了对Docker容器、Azure云服务和Kubernetes等技术的原生支持。
- 开放式标准:ASP.NET Core遵循开放式标准,如HTTP协议、RESTful API设计原则和OAuth身份验证。它还支持多种数据存储选项,包括关系型数据库、NoSQL数据库和文件系统等。
- 强大的工具集:ASP.NET Core提供了丰富的工具集,如命令行工具(CLI)、调试工具、自动重载等,以提高开发人员的生产力。
总之,ASP.NET Core是一个现代化、跨平台且高性能的Web应用程序框架,具有灵活性、可扩展性和易用性。它适用于构建各种类型的Web应用程序,从小型网站到大型企业级应用程序都可以使用ASP.NET Core来实现。
1.项目结构
Program.cs:项目的主启动类,监听请求
StartUp:项目配置类
Appsettings.json:配置数据,eg:数据库连接信息
launchSettings.json:项目运行配置
2.中间件
ASP.NET Core处理请求的方式看做是一个管道,中间件是组装到应用程序管道中用来处理请求和响应的组件。通常是一个可重用的类方法
每个中间件可以
(1)选择是否将请求传递给管道中的下一个组件。
(2)可以在调用管道中的下一个组件之前和之后执行业务逻辑
中间件原理
(1)ASP.NET Core的中间件通过一个类型Func<RequestDelegate,RequestDelegate>的委托对象来表示
(2)public delegate Task RequestDelegate(HttpContext context);RequestDelegate是一个处理HttpContext上下文的任务对象,每个Task中将完成特定的任务
(3)中间件并不孤立地存在,所有z注册的中间件最终会根据注册的先后顺序组成一个链表。
3.管道配置
(1)请求处理管道是在Startup.cs文件 Configure(IApplicationBuilder app,IWebHostEnvironment env)方法进行配置的
(2)IApplicationBuilder用User,Run,Map将多个请求委托连接在一起
(3)用Usexxx拓展方法,UseMiddleware<T>方法配置中间件
内置的常用中间件
中间件 | 描述 | 顺序 |
DeveloperExceptionPage | 生成一个页面,其中包含的错误信息仅适用于开发环境 | 在生成错误的组件之间,将此中间件注册为管道中的第一个中间件 |
StaticFiles | 为提供静态文件和目录浏览提供支持 | 如果请求与文件匹配,则为终端 |
Routing | 定义和约定请求路径 | 在UseEndpoints之前运行 |
CORS | 配置跨域资源共享 | 在UseResponseCaching之前运行 |
MVC | 用MVC/Razor Pages处理请求 | 如果请求与路由匹配,则为终端 |
管道短路与中间件顺序
当委托不将请求传递给下一个委托时,他被称为“让请求管道短路”。这是一种有意义的设计,因为可以避免不必要的工作。当中间件短路时,他被称为“终端中间件”,因为它阻止中间件进一步处理请求
自定义中间件
Public void Configure(IApplicationBuilder app,IHostingEnvironment env)
{
//middware中间件使用可重用的类【记录请求的ip地址】
App.UseMiddleware<IPMiddleware>();
//Run()方法,短路中间件
app.Run(asyn context=>
{
Await context.Response.WriteAsyn("hello world");
})
}
4.依赖注入
Dependency Injection,简称DI
ASP.NET Core在启动以及后续针对每个请求的处理过程中,各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET Core通过定义接口的方式对它们进行了“标准化”,我们将这些标准化的组件称为服务,ASP.NET Core在内部专门维护了一个IOC容器来提供所需的服务
服务的创建到销毁的过程完全交给IOC容器,大大降低了耦合度
什么是控制反转
IOC(Inversion of Control),控制反转,反转创建对象的权利,降低代码耦合度,是一种设计理念
什么是依赖注入
依赖注入(Dependency injection,DI)是一种实现对象及其依赖对象间松散耦合的技术
例如:A依赖B对象时,不是直接在A对象中实例化B或者静态引用B,解绑了A、B对象之间的依赖关系。
服务注册
ServiceCollection----<build>---> ServiceProvider
Public void ConfigureServices(IServiceCollection services)
{
//服务描述注册
Services.AddSingleton<IComputerBrand,LenovoComputer>();
}
依赖注入有两个核心组件:
IServiceCollection(负责注册实例)和IServiceProvider(简单的内置容器)
在StarUp类的Configservices方法中配置服务
注册实例方法:
AddSignleton();
AddTransient();
AddScoped();
构造器注入
Public class ComputerController:ControllerBase
{
Private Ienumerable<IComputerBrand>Brands;
Public ComputerController(Ienumerable<IComputerBrand>brands){
this.brands=brands
}
public void ShowBrand(){
foreach(IComputerBrand computer in brands){
Console.WriteLine(Computer.ToString()+"\n");
}
}
}
通过调用构造函数的方式来创建服务实例时,传入构造函数的所有参数必须先被初始化,存在多个构造函数数时,将会选择所有参数被实例化,而且参数值时最多的一个构造函数,如果未找到指定的构造函数,那么服务无法获得,服务抛出异常
默认服务
在Program中通过默认配置创建服务器时,会注册一些默认的服务。这些服务和我们自行注册的服务并没有任何区别,只要我们知道对应的服务类型,就可以通过构造器函数注入的方式获取并使用它们。
- ILoggerFactory
- Ilogger<>
- IApplicationBuilderFactory
- IHttpContextFactory
- Ioptions<>
- IStartupFilter
- IstartupFilter
- Istartup
- IHostingEnvironment
如果我们需要这些预注册的服务,我们可以按照我们熟悉的方式,通过构造函数的方式来使用它们。
使用Autofac替换默认的服务容器
步骤一:下载Autofac的Nuget包
步骤二:Program类中修改默认注入方式,采用Autofac
步骤三:新增服务注册类,多种方法注册服务描述信息
步骤四:修改配置类StartUp,增加ConfigureContainer方法,将注册在AutoFac的服务描述实例化到服务器中
5.配置和环境
配置
程序开发中,有些信息是要根据环境改变时,比如开发环境的数据库可能是本地数据,而生产环境下需要连接产生数据库,我们需要把这些信息放到程序外面,在程序运行时通过读取这些外部信息实现不改变程序代码使用不同环境的需求,这些信息就是“配置”。
较之传统通过App.config和Web.config这两个XML文件承载的配置系统,ASP.NET Core采用的这个全新的配置模型的最大一个优势就是支持多个不同配置源。我们可以将内存变量、命令行参数、环境变量和物理文件作为原始配置数据的来源,如果采用物理文件作为配置源,我们可以选择不同的格式,比如XML、JSON和INI等,如果这些默认支持的配置源形式还不能满足需求,我们还可以通过注册自定义ConfigurationProvider的方式将其他形式数据作为我们的配置来源。
配置优先级别
在构建ASP.NETCore项目时,将会在Program类中根据预配置的默认值加入配置服务。
ASP.NETCore中,AppSettings可以来自不同的配置源,且不同的配置源有不同的优先级别
1命令行参数
2环境变量
3UserSecret(用户机密)
4特定于环境的JSON档:
4.1Development(appSettings.Development.json)
4.2Production(appSetting.Production.json)
4.3其他(例如:APPSettings.Staging.json)
5json(appSettings.json)
1>2>3>4>5(同一配置信息)
读取配置
(1)启用读取配置档的功能,只需要在Startup中注入Iconfiguration即可
(2)配置信息逻辑上以树形结构存储,实际在内存中是以字典【Dictionary】键值对的形式存储,key是每个配置项所在配置节点在配置树种的路径,路径采用冒号(":")进行分割
public class Startup
{
private readonly Iconfiguration
_configration;
//注入配置文件服务
public StartUp(Iconfiguration configration)
{
_configration=configration;
}
}
6.ASP.NET Core MVC
6.1 MVC设计模式
6.2 MVC工作过程
MVC是用于实现应用程序的用户界面层的架构设计模式
Model(模型):包含一组数据的类
View(视图):负责在用户界面呈现内容
Controller(控制器):承载用户交互、模型运转,并最终选择视图进行渲染的组件
在MVC设计模式中,我们可以清楚地分离各个关注点,让他们各司其职,每个组件都有一个非常具体的任务要做,这种责任划分有助于根据复杂性缩放应用程序,因为这更易于编码、调试和测试
6.3 ASP.NET Core MVC概述
使用模型-视图-控制器设计模式构建网页应用和API的丰富框架,具有轻量级、开元、高度可测试的优势
包括的功能:
Routing(路由)
Model binding(模型绑定)
Model Validation(模型验证)
Dependency injection(依赖关系注入)
Filters(过滤器)
Areas
Web APIs
Razor view engine(Razor视图引擎)
Strongly typed views(强类型视图)
View Components(视图组件)
6.4 使用ASP.NET Core MVC
步骤一:注入服务
//依赖注入,服务管理
Public void ConfigureServices(IServiceCollection service)
{
//注入MVC的服务
Services.AddMvc();
}
步骤二:管道配置MVC中间件
Public void Configure(IApplicationBuilder app,IHostingEnvironment env)
{
If(env.IsDevelopment()){
App.UseDeveloperExceptionPage();
}
//路由配置规则默认为(controller=Home)/|action=index/("id")|
App.UseMvcWithDefaultRoute();
App.Run(async context=>
{
Await context.Response.WriteAsync("hello world")
})
}
6.5 路由
当来自浏览器的请求到达我们的应用程序时,请求会被精准定位到控制器指定操作方法中,处理、响应传入的http请求。此URL路由寻找过程是由ASP.NET Core MVC的路由机制来实现的
ASP.NET Core MVC中有两种路由技术
1 常规路由
2 属性路由
6.5.1 常规路由
常规路由约定了URL的路径:/[Controller]/[ActionName]/[Paramaters]该路由模板支持路由值约束[controller,action],默认值、可选值【用?标识】
路由格式可在Startup类中的请求管道中配置,如下所示:
App.UseMvc(routes=>{
//常规路由
Routes.MapRouter(name:"default",template:"[controller=Home]/{action=index}/{id?}")
})
- 第一段路径(Controller)决定要运行的控制器类,因此localhost:5001/HelloWorld 映射到He'llWorld控制器类
- 第二段路径(ActionName)决定类上的操作方法。因此localhost:5001/HelloWorld/Index触发HelloWorldController类的index方法
- 第三段路径(id),用户映射到模型实体
- 如果浏览到应用且不提供任何URL段,它将默认为上面突出显示的模板行中指定的“Home”控制器和“index”方法,这是根据默认值来确定的
使用常规路由,可以当开发人员快速构建应用程序,而无需定义每一个动作对应一个新的URL模式,整个控制器的URL具有一致性,有助于简化代码
6.5.2 特性路由
//路由前缀
[Router("/[controller]/[action]")]
Public class HomeController:ControllerBase
{
//localhost5001/Home/Index
Public string index(){
Return"This is the index method from HomeController";
}
//localhost:5001/Home/Index1 post请求
[HttpPost("/index1")]
Public string index1()
{
Return "This is the index1 Method from HomeContraller";
}
//localhost:5001/Home/Index1 get请求
Public string index2()
{
Return"This is the index2 Method from HomeController";
}
}
特性路由允许在控制器和方法使用添加特性的方式来定义应用程序的路由,这意味着路由定义紧邻着它们所关联的控制器和方法
常用Route和Http[verb]特性来设置路由表
6.6 模型绑定
ASP.NET Core MVC中的模型绑定数据从Http请求映射到操作方法参数。参数既可以是简单类型,例如字符串、整数或浮点,也可以是复杂类型,这是MVC一个强大的功能,MVC通过抽象绑定解决了这个问题。设置的路由模板为{controller=Home}/{action=index}/{id?}时,当MVC接收到来自https://localhost:5001/student/getStudentById/1的请求时,将会将1绑定到StudentController中的getStudentById的方法参数id中。
MVC将会尝试通过名称将请求数据绑定到操作参数上,MVC将使用参数名称和其公共可设置的属性名称查询每个参数的值。
6.6.1 为什么需要模型验证
平时项目中,为了确保存储到数据库中的数据信息准确,难免需要对提交参数进行一些参数正确性的校验。校验参数基本上是一个体力活,而且冗余代码繁多,也影响代码的可读性,我们需要一个比较优雅的方式来解决这个问题,让业务代码和校验逻辑分开,不再编写重复的校验逻辑
Public class StudentModel
{
Public int id{get;set;}
[Required(ErrorMessage="学生名必传")]
Public string name{get;set;}
[Required(ErrorMessage="班级信息必传")]
Public string className{get;set;}
[EmailAddress(ErrorMessage="邮箱格式错误")]
[Required(ErrorMessage="联系邮箱必传")]
Public string email{get;set;}
}
6.6.2 常用的内置验证属性
属性 | 作用 |
Required | 指定该字段是必填的 |
Range | 指定允许的最小值和最大值 |
MinLength | 使用MinLength指定字符串的最小长度 |
MaxLength | 使用MaxLength指定字符串的最大长度 |
EmailAddress | 是否为正确的邮件地址 |
RegularExpression | 正则表达式 验证提供的值是否与正则表达式指定的模式匹配 |
URL | 验证属性是否为网址格式 |
Public class StudentController:ControllerBase
{
[HttpPost]
Public string
saveStudent([FromBody]StudentModel srudent)
{
If(ModelState.IsValid)
{
If(repositoty.saveStudent(student))
Return"保存数据成功";
Return"保存数据失败";
}else{return"检查数据是否填写正常"}
}
}
6.6.3 模型验证异常统一返回格式
如果我们在每个需要验证的Action里面都写上述的判断逻辑,代码显得特别的冗余,我们可以在进入Action前进行参数验证。如果错误,直接返回符合后端开发的统一响应
(1)定义过滤器,模型未验证后返回通用的结果返回类
(2)配置过滤器
(3)关闭netcore自动处理参数校验机制
Services.Configure<ApiBehaviorOptions>(Option=>options.SuppressModelStatevaildFilter=true)