前言

想到要写这样一个系列博客,初衷有两个:一是希望通过一个实践项目,将.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. [nowcoder5671D]Data structure

    问题相当于统计$且\sum_{l\le x<y\le r且lca(x,y)=x}1=c(sz[x],2)-\sum_{son}c(sz[son],2)$,考虑用莫队来维护区间,那么相当于要支持: ...

  2. bsp工程管理

    1. bsp工程管理的目的 模块化项目,使得项目清晰 2. 代码 拷贝原来工程 创建文件夹 bsp就是工程驱动文件 imx6ull是和芯片有关的文件 obj是生成文件的文件夹 project 工程文件 ...

  3. idea解决Command line is too long. Shorten command line for ServiceStarter or also for Application报错

    找到 .idea\workspace.xml: 找到<component name="PropertiesComponent">,在里面添加<property n ...

  4. 解决fatal: unable to access '': Failed to connect to 127.0.0.1 port 1181: Connection refused的问题

    今天把项目提交的git远程的时候遇到一个问题 fatal: unable to access '': Failed to connect to 127.0.0.1 port 1181: Connect ...

  5. 8.2 k8s 基于StatefulSet运行mysql 一主多从 ,数据通过pv/pvc结合NFS服务器持久化

    1.准备mysql和xtrabackup镜像 下载mysql官方镜像并上传到本地harbor docker pull mysql:5.7 docker tag m ysql:5.7 192.168.1 ...

  6. C#.NET 操作Windows服务(安装、卸载)

    注意点: 1.安装时要请求到管理员权限. 2.卸载前,一定要停止掉Windows服务,否则需要重启或注销电脑.代码无法停止服务时,使用services.msc来停止. 开始: 1.新建一个名为&quo ...

  7. FJD1T3(LOJ 2773 学习轨迹)

    发现了\(FJOI\)原题 没什么想法,想到自己考场上连\(n^2\)做法都不会就很感慨. 考虑如果只选择一个序列的任务,那么肯定全部选择会更加优秀. 那么考虑如果我们选择了两个序列的一部分. 如果\ ...

  8. UOJ #129 / BZOJ 4197 / 洛谷 P2150 - [NOI2015]寿司晚宴 (状压dp+数论+容斥)

    题面传送门 题意: 你有一个集合 \(S={2,3,\dots,n}\) 你要选择两个集合 \(A\) 和 \(B\),满足: \(A \subseteq S\),\(B \subseteq S\), ...

  9. BZOJ 3926 诸神眷顾的幻想乡

    BZOJ 3926 诸神眷顾的幻想乡 开始看错题看成了每个点度数不超过20 后来翻了翻题解原来看错题的不止我一个 既然叶子数量不超过20,考虑树上的任何一条路径,以任何点为根时,如果它不是一条从上到下 ...

  10. BJ2 斜率限制器

    BJ2 斜率限制器 本文介绍斜率限制器取自于 Anastasiou 与 Chan (1997)[1]研究,其所利用的斜率限制器也是 Barth 与 Jespersen 限制器的一种修正形式,并且包含一 ...