Complete guide to building an app with .Net Core and React

解釋Walking skeleton是什麼

這是烏的咪的一堂課,一邊聽課一邊做點筆記。
Complete guide to building an app with .Net Core and React


1-2教安裝.NET SDK

mkdir Reactivities
之後移到這個資料夾
dotnet -h
可以列出可以用的指令
dotnet new -h

先建好專案資料夾Reactivities
然後cd到裡面,建一個sln檔案當作專案的container,所以打指令:
dotnet new sln
之後還要建其它的專案。分成四種

API
Application (包含所有的business logic)
Domain (包含domain entities)
Persistence (負責和database溝通)

所以打以下指令:
dotnet new classlib -n Domain
dotnet new classlib -n Application
dotnet new classlib -n Persistence
dotnet new webapi -n API
-n表示它會開資料夾

建起來非常的快喔


dotnet sln list
打這個可以知道這個sln有哪些專案

建完還要給它加到sln
dotnet sln add API/API.csproj ….
全部加完之後打dotnet sln list檢查

之後要加reference,因為API有依賴Application,
所以移到API的資料夾,打
dotnet add reference ../Application (要cd到想加reference的資料夾

接著又到Application資料夾,因為它依賴了Domain和Persistence,所以加一下
Persistence也依賴了Domain,給它加一下。

然後作者說
/bin
/obj
這兩個資料夾基本上不會去跟它互動,就像前端的build,所以他在VS Code就隱藏起來了。

都加完之後,就可以從API專案開始
dotnet run
dotnet watch run
用第二個指令,它可以偵測你的程式有沒有變動,有的話會重新restart、rebuild

在RUN專案的時候,它其實是跑Program.cs裡面的Main方法
Our API project needs to be hosted.
因為打內有一個web server叫Kestrel,所以我們的API就會在上面跑。用它來HOST我們的API。
Kestrel web server implementation in ASP.NET Core

另外作者還教說要改這邊:
appsettings.Development.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Information",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

把Microsoft改成Information,在log的地方會有比較多資訊。
(章節:Reviewing the project files and startup

這裡是一個construct,它inject了configuration

然後這邊的程式代表這讓我們可以讀到我們在這些設定檔(例如JSON檔)裡面的設定。

ConfigureServices這是一個Dependency injection container

這個叫做Dependency injection,在這裡有這個概念的解釋。
What is IoC Container or DI Container

打prop + tab可以寫Auto-implemented properties

之後作者快速的帶過 postman,說他有提供一些collocations 讓我們import


Section 4: Creating a CRUD application using the CQRS + Mediator pattern

CQRS常常看到,可是沒有特別去花時間理解,上次看過又忘了,現在再來複習一次

DB只有一個的時候,CQRS的優勢不太明顯
二個DB,不同用途的時候,CQRS的優勢就比較明顯

Implementing CQRS in ASP.NET Core Web API with MediatR (youtube.com)

Application跟API層之間需要有一個Mediator,讓Application可以跟API說「我正在處理資料喔」
Application專案裡面含Command, Query,command 可以 do something with an entity or an object,
and a query handler when we want to get data from our API.
List.cs就是query handler


Creating a domain entity
這個章節教我們用Guid來當ID用
它可以在server side產生,也可以在client side 產生,在client side 產生就不用等資料庫了。

Adding an Entity Framework Db Context
在Persistence專案安裝了Microsoft.EntityFrameworkCore.SqlLite 5.0.3
講師說記得要安裝跟runtime一樣的版本(假設是5.0.3就安裝5.0.3

提到Mediator Pattern,查了一下是什麼意思,讀了一下又花惹好多時間,還去查了一下UML了解那個線圖是什麼意思,有好多種,有菱形什麼的…。

然後加了connection string,就開始要ef大遷移了!它就是幫我們建立資料庫。

安裝Microsoft.EntityFrameworkCore.Design到API這個專案

在應用開式開始跑的時候,檢查有沒有DB,如果沒有,就建造一個

後來我改用sql server…
如果要改用其它的,參考Section22的Switching to PostGreSQL這一篇
首先要刪除Migrations這個資料夾,安裝想要用的Package
然後打以下這個指令

然後再佈署到我的FTP,發現成功轉換惹^O^ (之前失敗過,可能是沒有刪除資料夾就直接下指令了,Sqlite的跟SQL Server的不能混用)
dotnet ef migrations add IdentityAdded -p Persistence -s API
之後為了加註冊功能,再做一次migratioins

大概時隔一年?再來加一個Table看看



另外在2-13卡關中,因為我要用.NET6的寫法
後來發現講師在最後面有教!太好了
另外在建DB的時候一直提到
Service Locator Pattern
原來DbContext是一個services

後來開始寫API溜~先來建一個Controller,記得要繼承ControllerBase而不是Controller,原因在這裡有寫:
Create web APIs with ASP.NET Core
因為ControllerBase是純API在用,Controller則是可以return view的。

之後開始提到MediatR,對我來說開始有點複雜了起來。
Section 4 Creating our first query handler

在Application專案加了Create、Edit、Details、List

之後寫到Edit邏輯的API,需要安裝
AutoMapper.Extensions.Microsoft.DependencyInjection
到Application專案

這個套件還蠻好用的耶

之後要做一些參數的驗證了。
使用一個套件叫

FluentValidation.AspNetCore

安裝到Application。可以來看看它的文件
不過作者說這個文件有點過時了,它現在已經支援.NET 7了。
另外他還說文件上不建議用Automatic validation,但作者覺得不對,Automatic validation有支援Minimal APIs,而且也不會難Debug。(可能現在開發的案子比較不複雜)

Task<ActionResult<Activity>>
改成Task<IActionResult>
因為IActionResult可以收HTTP response

Identity
接下來要做註冊的功能

In the field of programming, a data transfer object is just an object to carry data between processes.
這篇講到DTO

Creating a token service

If there’s something that you’re creating that doesn’t involve data access, then it’s not a repository.
接下來開了Services資料夾,建一個token service檔案,要為每個user產生token。
token裡面可以有claim
Claims are just something that a user claims about themsleves.

※因為我心急想看看在線上會長怎麼樣子,所以開發一半就部署到線上去了,然後資料庫裡的table只有一開始的一個,之後EF新增的沒有,所以我查了一下要怎麼讓EF可以顧到Production上…查下來之後看來是直接叫EF產生SQL,直接到DB徒手下SQL了這個方法。

Applying Migrations
參考這篇,記得最後加個 -o filename.sql 就會產生SQL到指定的檔案(當然也要記得自己之前是在哪個點上…)

目前production的進度到IdentityAdded,後來更新到AddMangaTable,目前最新是AddItemsVersionTwo

記得要在API資料夾跑這個指令
run query前,把每一行GO刪掉,因為那是SSMS用的

做完馬上佈到production上,發現原本的API變成500 server error
先刪掉obj、bin資料夾,重新build solution,再按publish至local folder,然後上sharkAsp
把我的website關掉、restart pool,然後用FTP把publish資料夾的東西通通丟上去(包含runtime)
這樣嘗試之後恢復正常了,不確定是什麼問題。

===============================================================

在production上發現錯誤【HTTP Error 502.5 – Process Failure】
後來去看log,發現說我有一個套件沒有安裝,我檢查了一下確實是有安裝的,就刪掉bin和obj,重新restore,後來再build solution,build完後上傳到FTP去。
(在本機還有重裝一下.NET7 SDK,不確定之前是不是被我刪掉。還有安裝IIS Express,為了要run API,rider run API iis express的話port會是44xxx,只run另一個API就是 7000)


build完solution後,按publish,結果發現FTP禁止覆蓋一些檔案,例如 API.dll,用Rider也是有一樣的問題。
寫信去問客服,他竟然不久過後就回我了。

照著做就可以刪除了。真的是好客服捏!

複習一下加一個data model,做CURD的方法:

  1. 在Domain加上想要的class(記得要先加到git, 不然之後IDE會找不到…)
  2. 在Seed.cs塞一下資料
  3. 在資料庫下SQL同步一下
    dotnet ef migrations add 最新的 -p Persistence -s API(跑這行要在最外層資料夾跑)
    dotnet ef migrations script 最新的 -o test.sql (跑這行要在API資料夾跑) ※不能叫insert.sql,會塞不到資料
  4. 在Persistence的DataContext加上DbSet
  5. 加controller和在application專案加上List, Delete, Edit, Validator…
  6. 在MappingProfiles也要加Map