使用ASP.NET Core 3.x 構建 RESTful API - 1.準備工做

之前寫過ASP.NET Core 2.x的REST API文章,今年再更新一下到3.0版本。web

 

先決條件

我在B站有一個很是入門的ASP.NET Core 3.0的視頻教程,若是您對ASP.NET Core不瞭解,就能夠先看一下里面的基礎知識和API相關的內容,地址是:https://www.bilibili.com/video/av65313713/shell

預備知識:ASP.NET Core 和 C# 數據庫

工具:Visual Studio 2019最新版(VSCodeVS for Mac,Rider等也湊合),POSTMAN json

 

Web API 

Web API一般是指「使用HTTP協議並經過網絡調用的API」,因爲它使用了HTTP協議,因此須要經過URI信息來指定端點。 瀏覽器

 

API是Application Programming Interface的縮寫,是軟件的外部接口。也就是說,針對某個軟件,人們能夠知道它的外部功能,但並不知道(也不須要知道)它的內部運做細節,爲了從外部調用某些功能,須要指定軟件的調用規範等信息,這樣的規範就是API。 安全

因此Web API就是一個Web系統,經過訪問URI能夠與其進行信息交互。 網絡

 

大多數的 Web API 並非 RESTful API 

REST一詞是在2000年首次出現的,它是由Roy Fielding博士在《架構風格以及基於網路的軟件架構設計》這篇論文中提到的。他爲REST風格的API制定了一套約束規範或者叫架構風格 架構

因此準確的說,只有符合了Roy Fielding架構風格的Web API才能稱做是RESTful API。可是在實際開發中,有時候也有不徹底符合Roy Fielding架構風格的情形出現,針對這點我將會在稍後的文章中介紹。 mvc

 

MVC模式與RESTful API 

本系列文章中我將使用ASP.NET Core 3.0 MVC 來構建 RESTful API。 app

 

MVC(Model-View-Controller)我認爲是一種主要用來構建UI的架構模式。對於MVC模式其實有不少種解釋存在,可是不管那種解釋,它們都會強調鬆耦合和關注點分離(separation of concerns)。 

也是因爲這兩點的存在,程序的可測試性會大大提升,程序各部分的可複用性也很高。 

更多關於MVC的介紹,能夠看一下微軟的官方文檔:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/overview?view=aspnetcore-3.0 

 

注意:MVC不是一個完整的應用程序架構,我認爲它主要是用在展現層。因此實現UI就是MVC的一部分工做。 

 

如何把MVC映射到API

我認爲API一樣能夠看做是UI,它就是爲API消費者所提供的UI。 

讓咱們把MVC的三部分分別對應到API: 

  • Model,它負責處理程序數據的邏輯。這裏的Model能夠包含在當前級別獲取從存儲獲取數據的邏輯。可是有一些Model不包含任何邏輯,例如API所使用的DTOData transfer objects),這類的Model會被串行化到響應的body裏面。 

  • View,它是程序裏負責展現數據的那部分。在構建API的時候,View就是數據或資源的展現。如今一般使用JSON格式。 

  • Controller,它負責ViewModel之間的交互。包括處理用戶輸入,用API的術語來說,和API交互的「用戶」就是指API的消費者,這類用戶一般是另外一個程序,例如Angular的SPA程序。 

 

下面看看MVC這三部分的依賴關係: 

Model 
View 
Controller

Controller和View依賴於ModelController依賴於View,這也是分離的一個好處。 

換句話說,Controller會選取適當的View來展示給用戶,並一同把用戶請求的Model數據帶回去。 

 

當API消費者發出請求的時候,在Controller上面的Action將會被觸發,Controller會把接收到的輸入數據發送給負責業務處理邏輯或數據訪問邏輯的那部分程序。而後Controller會把Model返回給View,這裏的View就是資源的展現(一般是JSON格式)。 

 

接下來咱們就是用這套概念和ASP.NET Core 3.0 來建立RESTful API 

可是請注意,經過ASP.NET Core MVC或API模板創建出來的新項目,咱們並不會直接獲得RESTful(REST架構風格)的API。咱們必須在這個基礎上,本身構建RESTful的API,由於以前已經提到了,標準的RESTful API有不少約束和規範。 

 

建立ASP.NET Core 3.0 Web API項目 

打開VS2019,選擇項目模板ASP.NET Core Web Application 

Create a new project 
Recent project templates 
gRPC Service 
•3 ASP.NET Core Web Application 
Console App (.NET Framework) 
Windows Forms App (.NET Framework) 
Search for templates (Alt+S) 
All Platforms 
Console App (.NET Core) 
Clear 
All Project Types 
A project for creating a comman ne application that can n_ln on .NET Core on Windows, Linux and MacOS. 
Linux macOS 
dows Console 
ASP.NET Core Web Application 
ject templates for creating ASP.NET Core web apps and web APIs for Windows, Linux and macOS using .NET Core 
or .NET Framework. Create web apps with Razor Pages, MVC, or Single Page Apps (SPA) using Angular, React, or React * 
Redux. 
ma cas 
81azor App 
Windows 
Coud 
Semi ce 
Web 
n 
Project templates for creating Blazor apps that that run on the server in an ASP.NET Core app or in the browser on 
WebAssembIy. These templates can be used to build web apps with rich dynamic user interfaces (UIs). 
Linux macOS Windcms Coud Web 
Class Library (.NET Standard) 
A project for creating a class library that targets .NET Standard. 
C# Android iOS 
Azure Functions 
Linux macOS Windcms 
ibrary 
A template to create an Azure Function project. 
Azure Coud

 

而後爲項目和解決方案起名字,並選擇所在目錄: 

Configure your new project 
ASP.NET Core Web Application L 
Inux 
Project name 
Routine.Api 
Location 
o 
Solution name 
Routine 
Place solution and project in the same directory 
macOS 
Windcwvs 
Coud 
Service 
Web

 

而後選擇ASP.NET Core的項目模板: 

Create a 
.NET Core 
Empty 
An empty 
new ASP.NET Core web application 
ASP .NET 3.0 
ect template for creating an ASP .NET Core application. This template does not have any content in it. 
A project template for creating an ASP .NET Core application with an example Controller for a RESIfuI HITP service. 
This template can also be used for ASP .NET Core MVC Views and Controllers. 
Web Application 
A project template for creating an ASP NET Core application with example ASP NET Razor Pages content. 
Web Application (Model-View-Controller) 
A project template for creating an ASP .NET Core application with example ASP .NET Core MVC Views and 
Controllers. This template can also be used for RESIfuI HITP services. 
o 
Angular 
A project template for creating an ASP .NET Core application with Angular 
React.js 
A project template for creating an ASP NET Core application with React.js 
Get additional project templates 
Authentication 
No Authentication 
Change 
Adv ced 
Configure for HITPS 
Enable Docker Support 
(Requires Docker Desktop) 
Linux 
Author: Microsoft 
Source: .NET Core 3.010 
Create

首先要選擇ASP.NET Core 3.0 

這裏我選擇了API這個模板。在之前,我一般會選擇Empty模板,由於其它模板一般包含不少我不須要的東西,可是ASP.NET Core 3.0的API模板仍是比較乾淨的,能夠接受。 

最後,因爲本課程中不須要使用HTTPSDocker,因此把這兩個東西都勾掉。 

 

解剖 ASP.NET Core 3.0 API 模板項目 

點擊Create,項目就創建好了: 

Solution 'Routine' (I of I project) 
Routine-Api 
Connected Services 
Dependencies 
Analyzers 
•@ Frameworks 
properties 
launchSettingsjson 
Controllers 
c* WeatherForecastControIIer.cs 
appsettingsjson 
C" 
C" 
C" 
appsettings.DeveIopmentjson 
Program.cs 
Startup.cs 
WeatherForecast.cs

 

先看看 appsettings.json 

Routine.Api 
appsettings.json -E X 
Schema: http://json.schemastore.org/appsettings 
2 8' "Logging" • 
"LogLevel": 
"Default": "Information" , 
4 
"Microsoft": "Warning", 
5 
"Microsoft. Hosting. Lifetime": "Information" 
6 
7 
8 
"AllowedHosts": 
9 
10 
11

裏面只有默認的Log配置以及容許的Hosts 

 

appsettings.Development.json裏面: 

appsettings.json 
appsettings.DeveIopment.json -E X 
Schema: http://json.schemastore.org/appsettings 
2 8' "Logging" • 
"LogLevel": 
"Default": 
Routine.Api 
4 
5 
6 
7 
8 
9 
10 
"Debug" , 
"System": "Information" , 
"Microsoft": "Information"

也只有關於Log的默認配置。 

 

注意:您須要知道appsettings.json  appsettings.Development.json之間的關係,關於這點能夠看我ASP.NET Core 3.0的入門視頻教程,可是更簡單的辦法是看一下官方文檔:在ASP.NET Core中使用多個環境 

 

項目模板裏還有兩個類咱們不須要,因此把它刪掉,分別是WeatherForecastControllerWeatherForecast 

Routine.Api 
C" 
C" 
C" 
Connected Services 
Dependencies 
Analyzers 
•@ Frameworks 
Properties 
launchSettingsjson 
Controllers 
C* WeatherForecastControIIer.cs 
appsettings.json 
appsettings.DeveIopmentjson 
Program.cs 
Startup.cs 
Weather Forecast.cs

 

Program.cs 

public class Program 
public static void Main(stringC] args) 
CreateHostBuilder(args) . Build( ) . Run( ) ; 
public static IHostBuilder CreateHostBuilder(string[] args) 
Host. CreateDefaultBuilder(args) 
. ConfigureWebHostDefaults(webBuilder 
webBuilder . ) ; 
D;

這裏其實就是整個程序的入口,Main方法負責配置和運行整個Web程序。 

因爲這是一個Web項目,因此咱們還須要一個宿主(Host),這個宿主就是由下面的CreateHostBuilder方法來負責建立的。該方法首先會建立出一個實現了IHostBuilder接口的類(HostBuilder)的實例,而後調用它的Build方法來建立宿主(類型爲Host,實現了IHost接口),最後調用宿主上面的Run方法來運行程序。 

 

咱們暫時不修改這裏面的代碼,因此一切都會按照項目模板默認的配置進行,注意到下面的方法裏咱們使用到了Startup這個類: 

public static IHostBuilder CreateHostBuilder(string[] args) 
Host . CreateDefaul tBuilder( args) 
. ConfigureWebHostDefaults(webBuilder 
webBuilder . ) ;

因此咱們來看看Startup類。 

 

Startup.cs 

在這個類的構造函數裏: 

public class Startup 
O references 
public Startup(IConfiguration configuration) 
Configuration = 
configuration; 
I reference 
Configuration { get; 
public IConfiguration

咱們看到IConfiguration被注入了,這樣就容許咱們使用配置信息了,例如appsettings.json裏面的配置信息。 

 

下面有一個ConfigureServices方法: 

O references 
public void ConfigureServices(IServiceCollection services) 
services .AddControIIers( ) ;

這個方法負責向服務容器裏面註冊服務,已註冊的服務能夠經過依賴注入的方式在整個應用程序的其它地方進行使用。這裏的服務是一個比較廣義的概念,它就是一個在整個程序中作一些通用性操做的組件。 

 

這裏面只有一句話: 

3.0以前的版本里,這裏面應該寫的是services.AddMvc();,實際上在ASP.NET Core 3.0裏面這樣寫也是能夠的。可是AddMvc()裏面不只僅包含用於構建API的服務,還包含不少其它服務,例如構建View視圖和TagHelper相關的服務等。而AddControllers()方法只包含用於構建API的那些服務,例如Controller的支持、Model綁定、Data Annotation和格式化器等等。 

 

最下面還有一個Configure方法: 

O references 
public 
if 
Configure(IApplicationBuilder app, 
void 
(env . IsDevelopment( ) ) 
app . UseDeveloperExceptionPage( ) ; 
IWebHostEnvironment env) 
app . UseRouting( ) ; 
app . UseAuthorization( ) ; 
app.UseEndpoints(endpoints 
endpoints .MapControllers( ) ;

這個方法使用到了在ConfigureServices方法裏面註冊和配置的服務,因此這個方法是在ConfigureServices方法以後被調用的。 

Configure方法是用來指定ASP.NET Core Web程序是如何響應每個HTTP請求的。換句話說,也就是咱們在這裏配置請求的管道,配置的方法就是在這裏添加不少中間件(Configure方法裏面每個app.UseXxx就是添加一箇中間件,能夠查看中間件的官方文檔來了解更多)。 

 

在開發環境的時候,若是有異常發生,那麼會展現出一個異常頁面: 

if (env.IsDevelopment()) 
app . UseDeveloperExceptionPage( ) ;

 

app.UseAuthorization(),它會爲整個Web程序添加受權的能力。當你須要考慮API安全性的時候,這點就很重要了。一般受權配置是在ConfigureServices方法裏完成的,而我如今沒有對受權進行配置,可是app.UseAuthorization()仍然會容許API能夠被匿名的訪問。 

 

其它這幾句話: 

這幾句話都是用來指定如何把HTTP請求分配到特定的Controller Action上面的。也就是說這是關於路由的。 

 

很重要的一點就是:每個請求會按照代碼的順序穿越全部在這裏添加的中間件。可是每個中間件都有可能將請求短路,這樣的話請求就不會進入下一個中間件了,而會按照原路返回。 

請求處理模式顯示請求到達、經過三個中間件進行處理以及響應離開應用。

因此,添加中間件的順序很是重要。若是你把受權中間件放在了Controller的後邊,那麼即便須要受權,那麼請求也會先到達Controller並執行裏面的代碼,這樣的話受權就沒有意義了。 

 

修改項目啓動配置 

我喜歡使用控制檯啓動Web程序,這樣能夠很直觀的看到Log信息。爲達到這個目的,能夠修改launchSettings.json文件: 

 

修改後,在項目的Debug屬性裏也有體現: 

因爲我主要是使用POSTMAN來調用API,因此我不須要Launch Browser(啓動瀏覽器)。 

 

運行程序 

能夠看到程序能夠正常運行,而且在控制檯上有日誌的輸出。 

 

添加數據存儲功能

想要作RESTful API的話,咱們還須要數據,這裏我準備採用SQLite來做爲數據存儲,使用Entity Framework Core 做爲 ORM來與數據庫進行交互。針對Entity Framework Core 3.0 如何在ASP.NET Core 裏面使用,官方有個很不錯的教程 

 

下面開始在項目裏添加SQLiteEFCore 3.0(這部分官方文檔能夠點擊這裏)的支持: 

  • 首先,須要在咱們的項目裏經過Nuget添加 Microsoft.EntityFrameworkCore.Sqlite 這個包。 

  • 而後,還須要安裝 Microsoft.EntityFrameworkCore.Tools 這個包,它是用來作遷移的,關於這個包的更多功能解釋,能夠查看官方文檔 

 

創建Entities 

咱們先把項目的需求想的簡單一點,暫時咱們就作一個公司和公司員工的維護,兩個Entity,兩個表。 

 

公司(Company)的Entity: 

—namespace Routine.Api. Entities 
I reference 
public class Company 
O references 
public 
O references 
public 
O references 
public 
O references 
public 
{ get; set; } 
Guid Id 
{ get; set; } 
string 
Name 
{ get; set; } 
string 
Introduction 
ICollection<Employee> Employee$ 
{ get; 
set;

爲何使用Guid做爲主鍵的類型? 

 

員工(Employee)的Entity 

—namespace Routine.Api. Entities 
6 references 
public class Employee 
O references 
public 
public 
I reference 
public 
I reference 
public 
I reference 
public 
O references 
public 
O references 
public 
I reference 
public 
{ get; set; } 
Guid Id 
{ get; set; } 
Guid ?CompanyIcÉ 
string EmployeeNo { get; set; } 
string FirstName { get; set; } 
string LastName { get; set; } 
{ get; set; } 
Gender Gender 
{ get; 
DateTimeOffset Date0fBirth 
Company { get; set; } 
Company 
set;

 

還涉及到一個性別的枚舉: 

—namespace Routine.Api. Entities 
I reference 
public enum Gender 
1,

 

創建DbContext 

創建一個文件夾DbContexts,在裏面創建一個類名叫RoutineDbContext 

public class RoutineDbContext 
DbContext 
O references 
public RoutineDbContext(P>ContextOptions<RoutineDbContext> options) 
base(options) 
O references 
{ get; set; } 
public DbSet<Company> Companies 
O references 
{ get; set; } 
public DbSet<Employee> Employees 
O references 
protected override void OnModelCreating(ModelBuilder modelBuilder) 
modelBuilder . Entity<Company>( ) 
. Property(x x.Name).IsRequired().HasMaxLength(100); 
modelBuilder . Entity<Company>( ) 
. Property(x 
x. Introduction).HasMaxLength(500); 
modelBuilder . Entity<Employee>( ) 
. Property(x x. 
modelBuilder . ) 
. Property(x x. FirstName).IsRequired().HasMaxLength(50); 
modelBuilder . Entity<Employee>( ) 
. Property(x x. LastName).IsRequired().HasMaxLength(50); 
modelBuilder . Entity<Employee>( ) 
. HasOne( navigationExpression: x 
x.Company) 
. WithMany( navigationExpression: x 
x. Employees) 
.HasForeignKey(x x. Companyld) 
. OnDelete( DeleteBehavior . Restrict);

關於這個類的理解並非本文的重點,想知道詳細的解釋能夠查看這部分的官方文檔 

  • 這個類須要繼承於DbContext,而DbContext須要 DbContextOptions 才能工做,因此我採用了構造函數接收參數的形式來接收 DbContextOptions 

  • 中間的兩個DbSet屬性就能夠簡單的理解爲把Entity映射到了數據庫中的一個表。 

  • 最下面我重寫了OnModelCreating 這個方法。在裏面,我對兩個Entity的某些屬性作了一些限制。關於這部分的詳細內容,也能夠查看官方文檔。在方法的最後,我顯式的指明瞭兩個Entity之間的關係爲一對多關係,並指明瞭外鍵。其實按照約定,它們兩個之間的一對多關係是默認已經成立的,無需我來指明。 

 

添加種子數據 

仍是在RoutineDbContext這個類裏的OnModelCreating方法裏,我添加以下代碼來爲數據庫添加種子數據: 

這裏只添加了Company數據。 

 

創建Repository 

若是隻是用來說解RESTful API的話,不使用RepositoryService也行,就是直接在Controller裏面使用DbContext也能夠接受。可是我仍是簡單的寫一個Repository吧(這個Repository並非很規範),不然重複代碼可能比較多。 

 

首先看一下ICompanyRepository,也就是Repository的接口合約: 

裏面的功能我相信你們應該能看明白吧。 

 

而後看一下實現,CompanyRepository 

比較長。。。 

 

註冊服務 

在Startup的ConfigureServices方法裏把DbContextRepository註冊到容器裏: 

關於這部分的知識,能夠看官方文檔:服務生命週期配置DbContext 

 

修改Program 

爲了演示方便,我讓數據庫在每次程序啓動的時候都會被刪掉並從新進行遷移,同時設置好種子數據。這部份內容可查看遷移的官方文檔建立刪除API的官方文檔 

這裏只修改了Main方法: 

 

添加遷移 

打開VS2019的Package Manager Console,並輸入相似如下的命令來添加遷移: 

 

命令執行成功後,會生成一個Migrations文件夾: 

裏面包含着這個此次的遷移類和當前模型的快照 

 

運行程序 

能夠看到執行了一些SQL語句,而且出現的Log都是綠色的Info,這說明數據庫已經創建成功了。 

 

看一下項目文件: 

能夠看到數據庫已經成功的被創建了。 

 

打開數據庫: 

能夠看到種子數據已經成功寫入。 

相關文章
相關標籤/搜索