前言

想到要写这样一个系列博客,初衷有两个:一是希望通过一个实践项目,将.NET 6 WebAPI开发的基础知识串联起来,帮助那些想要入门.NET 6服务端开发的朋友们快速上手,对使用.NET 6开发后端服务的技术全貌有一个基本的认识和掌握,顺便把自己的技能树检查一遍;二是希望为国内的.NET环境有一些小小的帮助,最早我自己是做C#桌面应用出身的,但是随着互联网产业的繁盛和微软早年间的固执,使得国内的.NET开发环境收缩到几个固定的领域,以致于很多人今天依然认为C#和.NET不适合做大型的企业级应用,这个观念需要改变了。我无意比较技术和语言之间的好坏,只是更愿意看到国内的技术环境也能呈现出百家争鸣的状态。经过微软这么多年的改变和进步,.NET 6是一个很优秀的框架,这一点自从我最开始接触.NET Core 2起一年一年进化到现在,就深切地感受到,那好东西就拿出来和大家分享一下。

系列说明

在这个系列博客中,我将会使用.NET 6从头开始一步一步开发一个TodoList单体应用,在这个过程中尽可能将多的知识点独立成每篇文章,最后将应用通过Docker进行打包,并使用Github的Action和Azure Container Instance服务实现CI/CD。

选择TodoList的原因是这个项目足够简单,但是也足够去覆盖我希望覆盖到的知识点,对于读者来说,有以下一些建议的前置要求:

  • 需要会写C#,不需要.NET (Core)相关的开发经验。
  • 需要后端服务的开发经验,对基本的服务端相关特性有一定的认识。
  • 有对Clean Architecture的基本理解。

从下一篇文章开始,我们将从需求入手,通过大概30篇左右的文章来实现这个TodoList应用。

  • 使用.NET 6开发TodoList应用(1)——系列背景
  • 使用.NET 6开发TodoList应用(2)——项目结构搭建
  • 使用.NET 6开发TodoList应用(3)——引入第三方日志
  • 使用.NET 6开发TodoList应用(4)——引入数据存储
  • 使用.NET 6开发TodoList应用(5.0)——领域实体创建和配置
  • 使用.NET 6开发TodoList应用(5.1)——实现CQRS模式
  • 使用.NET 6开发TodoList应用(5.2)——实现AutoMapper
  • 使用.NET 6开发TodoList应用(6)——实现POST请求
  • 使用.NET 6开发TodoList应用(7)——实现GET请求
  • 使用.NET 6开发TodoList应用(8)——实现全局异常处理
  • 使用.NET 6开发TodoList应用(9)——实现PUT请求
  • 使用.NET 6开发TodoList应用(10)——实现PATCH请求
  • 使用.NET 6开发TodoList应用(11)——HTTP请求幂等性的考虑
  • 使用.NET 6开发TodoList应用(12)——实现接口请求验证
  • 使用.NET 6开发TodoList应用(13)——实现ActionFilter
  • 使用.NET 6开发TodoList应用(14)——实现查询分页
  • 使用.NET 6开发TodoList应用(15)——实现查询过滤
  • 使用.NET 6开发TodoList应用(16)——实现查询搜索
  • 使用.NET 6开发TodoList应用(17)——实现查询排序
  • 使用.NET 6开发TodoList应用(18)——实现数据塑形
  • 使用.NET 6开发TodoList应用(19)——实现HATEAOS支持
  • 使用.NET 6开发TodoList应用(20)——处理OPTION和HEAD请求
  • 使用.NET 6开发TodoList应用(21)——实现Root Document
  • 使用.NET 6开发TodoList应用(22)——实现API版本控制
  • 使用.NET 6开发TodoList应用(23)——实现缓存
  • 使用.NET 6开发TodoList应用(24)——实现请求限流和阈值控制
  • 使用.NET 6开发TodoList应用(25)——实现基于JWT的Identity功能
  • 使用.NET 6开发TodoList应用(26)——实现RefreshToken
  • 使用.NET 6开发TodoList应用(27)——实现Configuration和Option的强类型绑定
  • 使用.NET 6开发TodoList应用(28)——实现API的Swagger文档化
  • 使用.NET 6开发TodoList应用(29)——实现应用程序健康检查
  • 使用.NET 6开发TodoList应用(30)——实现本地化功能
  • 使用.NET 6开发TodoList应用(31)——实现Docker打包和部署
  • 使用.NET 6开发TodoList应用(32)——实现基于Github Actions和ACI的CI/CD

附:.NET 6 Web API项目代码上的变化

创建项目

mkdir ProjectName && cd ProjectName
dotnet new sln -n SampleApi
dotnet new project -f net6.0 -n SampleApi -o SampleApi
dotnet sln SampleApi.sln add SampleApi/SampleApi.csproj
dotnet restore
dotnet run -p SampleApi/SampleApi.csproj

.NET 6 WebAPI Program.cs的变更

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(); var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
} app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

Change 1: Top-level statements

顶级声明使得我们在编写Program类时可以不用再定义该类,省略Main函数定义,直接开始写方法体。编译器会在编译阶段为我们自动加上命名空间和相关定义。

Change 2: Implicit using directives

隐式using指令是编译器根据项目类型,在编译阶段自动生成一个名为CompanyEmployees.GlobalUsings.g.cs的文件,内容如下:

// <auto-generated/>
global using global::Microsoft.AspNetCore.Builder;
global using global::Microsoft.AspNetCore.Hosting;
global using global::Microsoft.AspNetCore.Http;
global using global::Microsoft.AspNetCore.Routing;
global using global::Microsoft.Extensions.Configuration;
global using global::Microsoft.Extensions.DependencyInjection;
global using global::Microsoft.Extensions.Hosting;
global using global::Microsoft.Extensions.Logging;
global using global::System;
global using global::System.Collections.Generic;
global using global::System.IO;
global using global::System.Linq;
global using global::System.Net.Http;
global using global::System.Net.Http.Json;
global using global::System.Threading;
global using global::System.Threading.Tasks;

也可以在CompanyEmployees.csproj工程配置文件中修改以下属性,禁用全局隐式using指令这一特性:

<!-- <ImplicitUsings>enable</ImplicitUsings> -->
<ImplicitUsings>disable</ImplicitUsings>

Change 3: No Startup class

到了.NET 6,陪伴我们好几个版本至今的ConfigureServices and Configure方法终于消失了,取而代之的是这两部分的配置都集中在了Program.cs中。曾经写过.NET Core WebAPI的小伙伴不难看出来现在应该写在哪里。

对于一些大型项目来说,这两部分我们肯定不能就这样写在Program.cs里面,后面将会想办法把这两部分单独拆开进行配置。

当然,老版本的含有Startup.cs的项目在.NET 6下打开没有任何问题。

关于Pipeline的一些知识点

Pipeline Sequence

  1. ExceptionHandler
  2. HSTS
  3. HttpsRedirection
  4. Static Files
  5. Routing
  6. CORS
  7. Authentication
  8. Authorization
  9. Custom Middlewares
  10. Endpoint Configuration

app.Run和app.Use

app.Run用于终止Pipeline的链式调用并向客户端返回

public static void Run(this IApplicationBuilder app, RequestDelegate handler);
public delegate Task RequestDelegate(HttpContext context);

app.Use用于向Pipeline中插入一段逻辑作为链式调用的其中一个环节

public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext,
Func<Task>, Task> middleware);

app.Map和app.MapWhen

这两个方法都是用于在middleware的链式调用中进行分支Pipeline调用链处理

public static IApplicationBuilder Map(this IApplicationBuilder app, PathString
pathMatch, Action<IApplicationBuilder> configuration) public static IApplicationBuilder MapWhen(this IApplicationBuilder app,
Func<HttpContext, bool> predicate, Action<IApplicationBuilder> configuration)

app.MapGet、app.MapPost、app.MapPut、app.Delete、app.MapMethods

在.NET 6中一个新增的特性叫做Minimal APIs,允许应用程序以这种形式响应客户端的请求,在快速构建微服务应用的过程中十分好用,在这个系列里,因为构建的是一个单体应用,这部分知识点我打算放到第二个系列关于微服务开发实践中去,看有没有更合适的场景去展示。

使用.NET 6开发TodoList应用(1)——系列背景的更多相关文章

  1. 使用.NET 6开发TodoList应用(3)——引入第三方日志库

    需求 在我们项目开发的过程中,使用.NET 6自带的日志系统有时是不能满足实际需求的,比如有的时候我们需要将日志输出到第三方平台上,最典型的应用就是在各种云平台上,为了集中管理日志和查询日志,通常会选 ...

  2. 使用.NET 6开发TodoList应用(2)——项目结构搭建

    为了不影响阅读的体验,我把系列导航放到文章最后了,有需要的小伙伴可以直接通过导航跳转到对应的文章 : P TodoList需求简介 首先明确一下我们即将开发的这个TodoList应用都需要完成什么功能 ...

  3. 使用.NET 6开发TodoList应用(4)——引入数据存储

    需求 作为后端CRUD程序员(bushi,数据存储是开发后端服务一个非常重要的组件.对我们的TodoList项目来说,自然也需要配置数据存储.目前的需求很简单: 需要能持久化TodoList对象并对其 ...

  4. 使用.NET 6开发TodoList应用(5)——领域实体创建

    需求 上一篇文章中我们完成了数据存储服务的接入,从这一篇开始将正式进入业务逻辑部分的开发. 首先要定义和解决的问题是,根据TodoList项目的需求,我们应该设计怎样的数据实体,如何去进行操作? 长文 ...

  5. 使用.NET 6开发TodoList应用(5.1)——实现Repository模式

    需求 经常写CRUD程序的小伙伴们可能都经历过定义很多Repository接口,分别做对应的实现,依赖注入并使用的场景.有的时候会发现,很多分散的XXXXRepository的逻辑都是基本一致的,于是 ...

  6. 使用.NET 6开发TodoList应用(6)——使用MediatR实现POST请求

    需求 需求很简单:如何创建新的TodoList和TodoItem并持久化. 初学者按照教程去实现的话,应该分成以下几步:创建Controller并实现POST方法:实用传入的请求参数new一个数据库实 ...

  7. 使用.NET 6开发TodoList应用文章索引

    系列导航 使用.NET 6开发TodoList应用(1)--系列背景 使用.NET 6开发TodoList应用(2)--项目结构搭建 使用.NET 6开发TodoList应用(3)--引入第三方日志 ...

  8. 使用.NET 6开发TodoList应用(7)——使用AutoMapper实现GET请求

    系列导航 使用.NET 6开发TodoList应用文章索引 需求 需求很简单:实现GET请求获取业务数据.在这个阶段我们经常使用的类库是AutoMapper. 目标 合理组织并使用AutoMapper ...

  9. 使用.NET 6开发TodoList应用(8)——实现全局异常处理

    系列导航 使用.NET 6开发TodoList应用文章索引 需求 因为在项目中,会有各种各样的领域异常或系统异常被抛出来,那么在Controller里就需要进行完整的try-catch捕获,并根据是否 ...

随机推荐

  1. 【Tool】JDK8 安装

    JDK8 2019-07-26  14:05:21  by冲冲 1. 下载 通常前往官网 https://www.oracle.com/technetwork/java/javase/download ...

  2. 从零开始学Kotlin第六课

    Kotlin调用java代码: 1.如果是内部工程的类,直接调用,如果是外部的工程项目按照java的方式将jar包导入进来. 2.实例化java对象 我们之前学java的时候实例化对象是这个样子的. ...

  3. 快速入门上手Markdown

    第一次接触Markdown是写代码初期看很多大佬的github,他们的项目一定会有一份文件叫Readme.md的文件 他们由一些简单美观的符号和汉字字母组成,编译之后成为一篇简单直观的文档 深入了解之 ...

  4. Codeforces 1500D - Tiles for Bathroom(贪心+队列)

    Codeforces 题面传送门 & 洛谷题面传送门 首先先讲一发我的 \(n^2q\log n\) 的做法,虽然没有付诸实现并且我也深知它常数巨大过不去,但是我还是决定讲一讲(大雾 考虑设 ...

  5. R 语言实战-Part 4 笔记

    R 语言实战(第二版) part 4 高级方法 -------------第13章 广义线性模型------------------ #前面分析了线性模型中的回归和方差分析,前提都是假设因变量服从正态 ...

  6. java数组中Arrays类

    使用Arrays类之后要先导入包,即在开头添加这行: import.java.util.Arrays 1,排序:Arrays.sort(数组名) 排序后为数组升序. 2,将数组转换成字符串:Array ...

  7. Excel—分组然后取每组中对应时间列值最大的或者最小的

    1.MAX(IF(A:A=D2,B:B)) 输入函数公式后,按Ctrl+Shift+Enter键使函数公式成为数组函数公式. Ctrl+Shift+Enter: 按住Ctrl键不放,继续按Shift键 ...

  8. linux常用目录和文件解析

    1. 一级目录 /dev 设备目录 /etc 系统配置及服务配置文件.启动命令的目录 /proc 显示内核及进程信息的虚拟文件系统 /tmp 临时文件目录 /home 普通用户家目录 /root 超级 ...

  9. 巩固javaweb第十二天

    巩固内容: HTML 图像- 图像标签( <img>)和源属性(Src) 在 HTML 中,图像由<img> 标签定义. <img> 是空标签,意思是说,它只包含属 ...

  10. SimpleNVR如何把安防监控画面推流到微信公众号直播

    背景需求 进入移动互联网时代以来,微信已成为许多企业除官网以外必备的宣传渠道,当3.2亿直播用户与九亿微信用户的势能增加,在微信上开启直播已成为越来越多企业的不二选择. 需求分析 微信公众号作为平台来 ...