Asp.net core 少走弯路系列教程(七)WebApi 学习
前言
新人学习成本很高,网络上太多的名词和框架,全部学习会浪费大量的时间和精力。
新手缺乏学习内容的辨别能力,本系列文章为新手过滤掉不适合的学习内容(比如多线程等等),让新手少走弯路直通罗马。
作者认为新人应该先打好基础,不要直接学习框架,例如先掌握 SQL 再使用 EFCore 框架。
作者只传授数年内不会变化的知识,让新手学习快速进入跑道受益终身。
分享使我快乐,请务必转发给同学,朋友,让大家都少走一些弯路!!
到此你已经初步掌握了 HTTP 协议,C# 语言基础知识,这一篇将带你进入 WebApi 服务器应用开发的环境。
对于 Web 服务端程序来讲,一般分两种请求内容,静态和动态:
- 静态的内容比如 .html/.css/.jpg,他们一般会存放在固定的 web 目录之内
- 动态的内容比如查询投票数量、发表博客文章
Asp.net core 框架入门
Asp.net core 框架,它是官方为数不多的优秀框架,其实蛮复杂不建议新手进行系统的全面学习,如果有条件甚至推荐先学习 expressjs 框架(nodejs)再来看 Asp.net core 会简单很多。
创建一个 WebApi 程序很简单,在控制台使用命令:
dotnet new webapi
然后你就可以 F5 运行项目了,快点打开 ide 试试吧!
- AddControllers/MapControllers 应用 Controllers 目录下的控制台类
- AddSwaggerGen/UseSwagger/UseSwaggerUI 应用 Swagger 接口管理器,你可以把它发给前端开发者,提供了哪些 HTTP 接口一目了然
Controller 控制器
- WeatherForecastController 继承 ControllerBase
- [Route("[controller]")] 注解指定 HTTP 请求的路径是 WeatherForecast
- Get 方法 [HttpGet("GetWeatherForecast")] 指定 HTTP 请求的方法为 GET,最终请求的路径是 WeatherForecast/GetWeatherForecast
- Get 方法返回值最终被序列化成 Json 格式返回给浏览器
思考:如果使用 [HttpPost] 是不是指定方法为 POST?
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet("GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
之前讲 HTTP 协议时,有讲到 QueryString、Form、JSON 三种请求报文的参数格式,服务器获取参数的办法:
[HttpGet("QueryString")]
public string QueryStringTest([FromQuery] int id, [FromQuery] string wd)
{
return id.ToString() + ", " + wd;
}
[HttpPost("Form")]
public string FormTest([FromForm] int id, [FromForm] string wd)
{
return id.ToString() + ", " + wd;
}
[HttpPost("JSON")]
public string JsonTest([FromBody] JsonTestInputModel json)
{
return json.id.ToString() + ", " + json.wd;
}
class JsonTestInputModel
{
public int id { get; set; }
public string wd { get; set; }
}
关于异步,建议先把同步熟练之后再学习不迟,混起来学机制不明白还容易乱用。
什么是依赖注入(Denpendency Injection)
到底依赖注入是什么? 为什么要用它? 初学者特别容易对控制反转IOC(Iversion of Control),DI等概念搞晕。
1、首先我们得知道什么是依赖
当一个类需要另一个类协作来完成工作的时候就产生了依赖。比如我们在AccountController这个控制器需要完成和用户相关的注册、登录 等事情。其中的登录我们由EF结合Idnetity来完成,所以我们封装了一个EFLoginService。这里AccountController就有一个ILoginService的依赖。
2、什么是注入
注入体现的是一个IOC(控制反转的的思想)。在反转之前 ,我们先看看正转。
private ILoginService<ApplicationUser> _loginService;
public AccountController()
{
_loginService = new EFLoginService()
}
大师说,这样不好。你不应该自己创建它,而是应该由你的调用者给你。于是你通过构造函数让外界把这两个依赖传给你。
private ILoginService<ApplicationUser> _loginService;
public AccountController(ILoginService<ApplicationUser> loginService)
{
_loginService = loginService;
}
把依赖的创建丢给其它人,自己只负责使用,其它人丢给你依赖的这个过程理解为注入。
3、为什么要反转?
为了在业务变化的时候尽少改动代码可能造成的问题。比如我们现在要把从EF中去验证登录改为从Redis去读,于是我们加了一个 RedisLoginService。这个时候我们只需要在原来注入的地方改一下就可以了。
因为EFLoginService和RedisLoginService都实现了接口ILoginService,所以我们直接在调用方传入RedisLoginService即可。(即将EFLoginService替换为RedisLoginService)
4、什么是容器?
上面我们在使用AccountController的时候,我们自己通过代码创建了一个ILoggingServce的实例。想象一下,一个系统中如果有100个这样的地方,我们是不是要在100个地方做这样的事情? 控制是反转了,依赖的创建也移交到了外部。现在的问题是依赖太多,我们需要一个地方统一管理系统中所有的依赖,所以容器诞生了。
容器负责两件事情:
- 绑定服务与实例之间的关系
- 获取实例,并对实例进行管理(创建与销毁)
Asp.net core DI
在.NET Core 中 DI 的核心分为两个组件:IServiceCollection和 IServiceProvider。
- IServiceCollection 负责注册
- IServiceProvider 负责提供实例
builder.Services
//.AddTransient<ILoginService, EFLoginService>() //每一次GetService都会创建一个新的实例
.AddScoped<ILoginService, EFLoginService>() //在同一个Scope内只初始化一个实例
//.AddSingleton<ILoginService, EFLoginService>(); //整个应用程序生命周期以内只创建一个实例
提示:每个 HTTP 请求都会创建一个 Scope 生命范围,所以 AddScoped 是最常用的方法。
public class WeatherForecastController : ControllerBase
{
private readonly ILoginService _loginService;
public WeatherForecastController(ILoginService loginService)
{
_loginService = loginService;
}
}
中间件管道
app.Use(async (context, next) =>
{
Console.WriteLine("middleware1 : in");
await next.Invoke();
Console.WriteLine("middleware1 : out");
});
app.Use(async (context, next) =>
{
Console.WriteLine("middleware2 : in");
await next.Invoke();
Console.WriteLine("middleware2 : out");
});
app.Run(async context =>
{
Console.WriteLine("Hello World");
await context.Response.WriteAsync("Hello World");
});
Asp.net core 框架还有很多知识,但是对新手而已学到这里算入门了,千万不要指望一下能吃下所有内容(贪吃蛇的后果),只有反复的实战才能彻底领会贯通。
到这里,你已经对 Asp.net core 框架有了初步的认识,为我们以后深入打下了基础,下一篇我们学习 数据库 CRUD 增删改查 知识吧!
系列文章导航
- (一)了解 W3C
- (二)HTML 学习
- (三)CSS 学习
- (四)JavaScript 学习
- (五)了解 HTTP 协议
- (六)C# 语法学习
- (七)WebApi 学习
- (八)数据库 CRUD 增删改查学习
- (九)待续。。
原创保护,转载请注明出处:https://www.cnblogs.com/FreeSql/p/16782488.html