前文:
ASP.NET Core RESTful风格 学习总结(持续更新)
项目设置:
项目依赖:
Dependencies文件夹:
项目所有的服务依赖及框架都会安装在这个文件夹
其中框架文件夹中包含两个框架:
Microsoft.NETCore.App:
是项目的基础框架,它包含了对代码编译,运行,部署的处理。
Microsoft.AspNetXore.App:
基于基础框架引入的应用层框架,它包含了一系列应用层的服务,认证服务,授权服务,诊断服务,http的请求处理服务,以及文件访问,日志记录,依赖注入等等。
依赖管理NuGet:
用于项目构建和依赖解析的工具,可以完成项目依赖的自动安装,解决依赖冲突。
项目的运行时设置appsetting.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Logging:日志设置
? LogLevel:日志级别;
? Default:日志默认信息;
? …
? AllowedHosts:对托管服务器的设置
appsetting.json文件能保存的设置远远对于上面我们所看到的内容
例如数据库链接设置,第三方信息,账号密码等等
项目启动IIS服务器与.NET Core内建的KESTREL服务器
IIS服务器与.NET Core内建的KESTREL服务器
- IIS 服务器只能运行于windows上
- .NET Core 服务器 KESTREL可以跨平台
项目的配置信息(启动)设置launchSettings.json
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:4123",
"sslPort": 44304
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"FakeXieCheng": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
- launchSettings.json只处理项目的启动设置
- “profiles”:服务器端口的信息定义在这里
- ”IIS Express“是IIS服务器的配置信息
- ”项目名“是.NET Core 服务器KESTREL的配置信息
- “applicationUrl”:定义了https和http的端口信息,可随意修改端口号
Program.cs和Startup.cs
项目启动入口:Program.cs
- Program.cs中定义了项目的主方法Main函数,而Main函数只做了一件事情:通过CreateHostBuilder创建并运行了虚拟托管服务器
CreateHostBuilder
CreateHostBuilder所有的配置过程:
在其源码中注释可以了解到CreateHostBuilder所有的配置过程:
-
查看程序的运行环境 -
通过运行环境启用相应的配置文件appsettings.json -
加载程序集assembly运行系统的所有核心代码 -
设置环境变量,日志,以及系统的反转控制IOC容器 public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
CreateHostBuilder 方法中Host为虚拟网站托管主机
CreateDefaultBuilder方法实现的四件事:
- 加载主机以及应用程序的配置信息
- 配置日志记录
- 设置WEB服务器
- 设置ASP.NET应用程序的托管程序
Startup.cs:
默认生成
Startup:
- 依赖注入:ConfigureServices中注入各种服务组件的依赖
- 中间件:在Configure中创建中间件,设置请求通道
ConfigureServices注入各种服务组件的依赖
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(options => options.UseSqlServer("name=ConnectionStrings:DefaultConnection"));
services.AddMvc();
services.AddTransient<INoodleRepository, NoodleRepository>();
services.AddTransient<IFeedbackRepository, FeedbackRepository>();
}
其中注册ASP.NET Core 自带的服务和自定义服务
例如注册ASP.NET Core自带服务的MVC组件
services.AddMvc();
? 注册控制器组件
services.AddControllers();
而ASP.NET Core Mvc组件的各种方法都可以使用了
Configure配置http请求通道(Request Pipline):
Configure:在运行时被调用,ASP.NET Core 提供了内置的IOC容器
-
检查&处理http请求 -
交由中间件MIddleware处理 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m6EoQ4qw-1641831459107)(E:/Note/image-20220109211554168.png)] -
如果当前环境为Development则使用开发者异常界面 if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
Configure完整代码
?
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseRouting();
//新中间件短路直接响应
/* app.Run(async (context) => {
await context.Response.WriteAsync("HI");
});*/
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//在这里进行新路由
endpoints.MapGet("/test", async context =>
{
await context.Response.WriteAsync("HI");
});
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
使用Mvc的映射代替直接对路由进行映射
endpoints.MapControllers();
启动Mvc路由映射中间件
环境变量与中间件:
-
请求通道由IApplicationBuilder创建 -
IWebHostEnvironment虚拟主机的环境变量: 开发过程中,往往会分成: 开发环境 Development 集成环境 Intergration 测试环境 Testing 预发布环境 Staging 生成环境 production[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X8tyicSX-1641831459109)(E:/Note/2.jpg)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YzHXiYEW-1641831459109)(E:/Note/1-16418041944201.jpg)] -
每个中间件都可以截获,修改,传递请求对象,输出响应对象,例如代码中 //新中间件短路直接响应
/* app.Run(async (context) => {
await context.Response.WriteAsync("HI");
});*/
-
在特定情况下,某些中间件可以做短路处理,直接向前端输出响应对象 -
所有中间件共用一个请求通道 -
不同中间件之前可以通过嵌套来获得更强大的处理能力 -
每一中间件截获的请求对象都来自于上一中间件的响应对象,所以中间件是有一定顺序的
路由
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-psdw7lfV-1641831459110)(E:/Note/d1b8b6fe52e6ba23694f905a3ae5448.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yyp2wA60-1641831459111)(E:/Note/a67f3344679a35d5396973d397e9ead.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u0gAjvn9-1641831459112)(E:/Note/fc77d646e9e0256e44b72d983c0c697.jpg)]
两种路由模式:
传统路由(使用路由表) Conventional routing:**
-
Url被分段解析为Controller和action两个部分 例如:{域名}/{controller}/{action} -
使用路由表(routing table)来设置路由规则,使用中间件: 例如: routes.MapRoute(
name:"default",
templete:"{controller=Home}/{action = index}"
)
3.使用默认路由:
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
特征注释路由 Attribute routing
app.UseEndpoints(endpoints =>
{
//特征注释路由来映射Controller与action的关系
endpoints.MapControllers();
});
HomeController中
直接方式:
namespace Puzi.Controllers
{
[Route("Home")]
public class HomeController : Controller
{
[Route("index")]
public IActionResult Index()
{
return View();
}
[Route("privacy")]
public IActionResult Privacy()
{
return View();
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tdpR16dE-1641831459112)(E:/Note/1-16418041944201.jpg)]
映射方式:
[Route("[Controller]")]将会映射HomeController在内的所有Controller
namespace Puzi.Controllers
{
[Route("[Controller]")]
public class HomeController : Controller
{
[Route("[action]")]
public IActionResult Index()
{
return View();
}
[Route("[action]")]
public IActionResult Privacy()
{
return View();
}
}
}
namespace Puzi.Controllers
{
[Route("[Controller]/[action]")]
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
}
}
自定义路由
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
-
将统配所有Controller和action -
controller=Home, action=Index将会使网站打开以后页面根目录会默认到Home与index -
同时特征注释路由可以与其它方式通用以增强效果 namespace Puzi.Controllers
{
[Route("PhoneShop/[Controller]/[action]")]
public class PhoneController : Controller
{
public String test()
{
return "hi";
}
public IActionResult Index()
{
return View();
}
}
}
MVC和三层架构
MVC
一.什么是MVC
- 软件工程的架构方式
- 模型(Model),视图(View)和控制器(Controller)
- 分离业务操作,数据显示,逻辑控制
二.视图View
三.模型Model
- MVC架构的核心
- 表示业务模型或数据模型
- 业务逻辑,如算法实现,数据的管理,输出对象的封装等
四,控制器Controller
- 接受用户的输入,并调用模型和视图去完成用户的请求处理
- 不处理数据
五,MVC架构的数据如何流动
图示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Saw5SEl4-1641831459113)(E:/Note/8b536afafa3a19e8ec83fc76f5253da.jpg)]
步骤解读:
- url打开主页
- 请求信息通过请求通道传递到主页对应的控制器HomeController
- HomeController寻找对应的数据模型
- 数据模型去对应的数据库获得HomeController希望得到的原始数据
- 数据模型进行业务操作,将原始数据封装;例如封装物品的名称,价格,图片等等
- 将封装好的数据交回给HomeController控制器
- HomeController取得数据后,会将这些数据传递给视图View
- 视图拿到数据后会把数据添加进动态Html中
- 通过http的形式把html文件发送到用户的浏览器
- 用户查看到主页信息。
- 用户点击继续查看
- 形成闭环
详解:
? url打开主页,然后请求信息就会通过请求通道传递到主页对应的控制器HomeController,随后,HomeController开始响应,HomeController会去寻找对应的数据模型,随后数据模型开始工作,它会去对应的数据库获得HomeController希望得到的原始数据,然后进行业务操作,将原始数据封装一下,比如封装物品的名称,价格,图片等等,随后将封装好的数据交回给HomeController控制器,当HomeController取得数据后,就会将这些数据传递给视图View,而视图拿到数据后会把数据添加进动态Html中,最后通过http的形式把html文件发送到用户的浏览器中,最后,用户便能看到主页信息,随后用户点击继续查看,从此,形成闭环。
六.MVC的优点
(1)耦合性低
视图层和业务层可以分离:
可以只更改视图层代码而不需要重新编写模型和控制器的代码,比如,改写jsp,html,css或js的代码,并不需要重启服务器。
同样,一个应用的业务流程或业务规则发生改变,只需要改变mvc的模型,因为模型与控制器,视图相分离,所以很容易改变业务程序的数据层和业务规则。
(2)可复用性高
MVC的所有组件都具有高可复用性,随着技术的不断进步,需要越来越多的方式访问应用程序,MVC模式允许各种各样不同样式的视图来访问同一服务端的代码,多个视图可共用一个模型,比如,用户可以通过web应用,也可以通过手机app来订购同样的产品,虽然订购的方式不一样,但是处理订购的业务是一样的,由于模型返回的数据并没有发生改变,所以同样的功能可以被不同界面使用
(3)可维护性高
分离视图和业务逻辑可以使得web应用易于维护和修改,比如,如果向更改业务逻辑,只需要更改业务逻辑,如果想更改视图,只需要去更改视图,如果想增加功能,只需要增加功能。便于维护和后期代码更新。
七.MVC的缺点
(1)定义不明确,学习曲线陡
大家都是依照自己的经验来解释和使用MVC,而MVC内部原理比较复杂,组合了多种设计模式,完全理解MVC较为困难,对新手不友好
(2)结构复杂
MVC并不适合小型,甚至中型项目,对于简单的界面,严格遵循MVC反而增加结构的复杂性,产生过多的数据操作导致运行效率底下。
(3)数据流动效率低
依据操作模型的接口不同,视图可能需要多次调用才能获得足够的数据显示,对于未变化的数据,频繁的访问模型,也可能造成操作性能下降。
三层架构
一.UI层:
表示用户界面
二.BLL:
业务逻辑层,处理核心业务以及数据封装
三.DAL层:
表示数据访问
四.三层架构的数据如何流动
图示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gmb30TBD-1641831459113)(E:/Note/1-16418293170482.jpg)]
步骤:
- 根据数据库创建DAL。
- DAL来获取和映射数据。
- DAL得到数据后,传递给BLL业务逻辑层进行数据验证,数据转换以及对象封装。
- 封装好的对象传递给UI层显示给用户
详解:
首先,需要一个数据库,根据数据库,创建DAL来获取和映射数据,得到元组数据后,传递给BLL业务逻辑层进行数据验证,数据转换以及对象封装,最后,封装好的对象传递给UI层显示给用户
MVC VS 三层架构
相同点:
不同点:
- 三层架构面向接口编程,而三个层级之间完全解耦,完全可替换。自下而上
- MVC每个部分都是紧密结合的,它的核心不是解耦,而是重用(即同样的Model,可以使用不同的控制器,搭配不同的视图,实现不同的内容)。
- 三层架构是自下而上的,而MVC是水平结构的,只有调用关系,而没有层级关系,所有的数据流动和显示都是通过数据绑定,事件驱动所处理的
Controller:
ApiController
标准模板ApiController:
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace FakeXieCheng.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TestApiController : ControllerBase
{
// GET: api/<TestApiController>
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<TestApiController>/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
// POST api/<TestApiController>
[HttpPost]
public void Post([FromBody] string value)
{
}
// PUT api/<TestApiController>/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/<TestApiController>/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
三种方式构建ApiController:
一,直接在Api名称后加上Controller
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace FakeXieCheng.Controllers
{
[Route("api/shoudongapi")]
public class ShoudongApiController
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
}
二,在类前加上[Controller]属性
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace FakeXieCheng.Controllers
{
[Route("api/shoudongapi")]
[Controller]
public class ShoudongApi
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
}
三,普通类继承Mvc的Controller父类
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace FakeXieCheng.Controllers
{
[Route("api/shoudongapi")]
public class ShoudongApi:Controller
{
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
}
思考
1. Kestrel服务器 vs IIS服务器?
Kestrel可以跨平台,IIS只能在Windows上使用。
2. 什么是中间件?什么是请求通道?
请求通道是Http请求从接收到处理完成,经过的一系列处理环节。 中间件就是一个个环节上的工具,可以根据这一块的框架自定义中间件。
3.schema是数据库中的什么?
不同的教材对schema的定义也不太一样,甚至是不同的数据库对Schema的使用也不完全一样,比如mysql中schema就相当于DB,sql server中schema却描述的是每张表的结构。一般来说,我们说到schema指的是数据库中表的结构、主键、外键、视图、各种关系的总和。
|