從無到有建立一個前後端分離的新專案(Angular + .Net Core WebAPI + PostgreSQL)

最近工作剛好有個自己從無到有建置一個專案的機會,自己也是第一次從無到有的自己建置一個專案,機會難得,紀錄一下整個過程,大致會有下列幾個主要步驟:

  1. 建立後端.Net Core WebAPI新專案
  2. 建立Angular新專案,並安裝Angular Material & Bootstrap
  3. 建立資料(Repository)層
  4. 後端API權限設定
  5. Angular呼叫後端WebAPI & CORS處理

  • 建立WebAPI新專案

1.選擇專案類型

2.設定專案


  • 建立Angular新專案,並安裝Angular Material & Bootstrap

1.輸入下列指令建立Angular專案資料夾

ng new [ProjectName] --routing --style scss

2.安裝Angular Material

npm install --save @angular/material @angular/cdk
npm install --save @angular/animations
ng add @angular/cdk

3.安裝好後可以先ng s看看能不能順利執行Angular的初始頁面,不能的話有可能是Angular Material的版本不支援目前的Angular,要更新Angular,可以參考How to Upgrade from Angular 14 to Angular 15 Version Example

ng update @angular/cli @angular/core

4.在app.component.html加上button測試看看Angular初始頁面

<button>Hello World!</button>
<br/>
<button mat-raised-button color="primary">Hello World!</button>

<router-outlet></router-outlet>
可以成功看到Angular初始頁面了,但是沒有任何樣式

5.在style.scss裡加上theme樣式

@import '@angular/material/prebuilt-themes/deeppurple-amber.css';
Angular Material安裝成功

6.可以開始進行前端Layout切版了


  • 建立Repository層

1.建立新專案(LCM.Repositories),專案範本選擇類別庫
 

2.NuGet下載安裝[Microsoft.EntityFrameworkCore]

3.由於公司是使用PostgreSQL,所以我們要另外從NuGet下載安裝[Npgsql.EntityFrameworkCore.PostgreSQL]。如果要與MS SQLServer連線,要記得另外安裝[Microsoft.EntityFrameworkCore.Relational]

4.安裝[ef core power tools],之後就不用自己輸入指令建立Dbcontext檔案 & 更新資料庫模型,使用說明以及下載連結可以參考這篇[.NETCore] 安裝 Entity Framework Core - 使用 EF Core Power Tool

5.建立Dbcontext檔案(如果使用PostgreSQL的話,要先安裝Npgsql PostgreSQL Visual Studio 工具)

6.安裝好後再專案點選右鍵 => EF Core Power Tools => Reverse Engineer,並依照下列圖片進行操作:
 

選Add Database Connection
變更資料來源為PostgreSQL Database,如果沒有安裝步驟4.的工具在變更資料來源會找不到PostgreSQL Database
設定連線資訊並測試連線
選擇要匯入的Table
設定參數,設定內容請參考Ref3. & 4.
DbContext & Model建置完成

7.appsettings.Development.json新增DB連線字串,如果有其他環境的話(例如:SIT. UAT. PRD),記得要順便新增這些環境的appsettings.json檔

  "ConnectionStrings": {
    "CAEDB01Connection": "{DB連線字串}"
  }

8.LCM.Web記得加入參考LCM.Repositories,這樣才能注入Context連線文本。在Program.cs裡註冊Dbcontext服務。如果要與MS SQLServer連線,要記得另外安裝[Microsoft.EntityFrameworkCore.SqlServer]. [Microsoft.Entityframeworkcore.Relational]. [Microsoft.Data.SqlClient],然後把UseNpgsql換成UseSqlServer。

builder.Services.AddDbContext<CAEDB01Context>(options => options.UseNpgsql(builder.Configuration.GetConnectionString("CAEDB01Connection")));

9.測試呼叫API,透過EF Core取得DB的資料。

        [HttpGet("QQ")]
        public IEnumerable<Object> GetTestData()
        {
            return _context.Test_Table.ToList();
        }
呼叫成功

這樣Repositories層的建置就算是完成了,表現層已經可以跟Repository層要資料了。不過以三層式架構來說,通常中間會在插一層服務(Service)層跟資料(Data)層,不會由表現層直接跟Repositories層要資料。至於權限管理又是另外一回事了,目前的測試API是還沒有加上權限驗證功能的。(關於更多的三層式架構可以參考:菜雞新訓記 (5): 使用 三層式架構 來切分服務的關注點和職責吧。這篇文章很推薦去看看,講得不會太複雜,手把手教學建立三層式架構專案)


  • WebSite權限設定

1.如果要使用windows登入驗證的話,記得要到launchSettings.json的iisSettings把windowsAuthentication設定為true

2.接著在到Program.cs裡面註冊驗證服務

/*Add Authentication (註冊驗證)*/
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme);
builder.Services.AddAuthentication(Microsoft.AspNetCore.Authentication.Negotiate.NegotiateDefaults.AuthenticationScheme).AddNegotiate();

//Middleware啟用授權功能,要搭配[Authenrization],沒加上[Authenrization]還是不會進行授權驗證
app.UseAuthorization();

//不管有無[Authenrization],都會進行授權驗證
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers().RequireAuthorization();
});

  • Angular呼叫後端WebSite API & CORS處理

1.先進行環境變數設置,於Angular專案的.\environments\environment.ts裡面設定apiBaseUrl,也就是後端API的Server位置。如果有其他環境的話(例如:SIT. UAT. PRD),記得要順便新增這些環境變數的environment.ts檔

export const environment = {
  production: false,
  webSite: 'http://localhost:4200',
  apiBaseUrl: 'https://localhost:44389/api',//port號自行改成WebSite的launchSettings.json裡設定的port號
};

2.在我們要呼叫的API URL前加上apiBaseUrl這個環境變數,或是可以自己寫個interceptor檔,在每個request url前加上apiBaseUrl環境變數也可以

  test(): Observable<any> 
  {
    const url = `${environment.apiBaseUrl}/TestFeature/Test`;
    const options = this.generatePostOptions();

    return this.httpClient
    .get<IResultDto<any>>(url, options)
    .pipe(
      tap((_) => console.log('execute TestFeature.Test'))
      //, map((result) => this.processResult(result))
    );
  }

3.在前端畫面新增一個測試button,並加上(click)事件呼叫測試API

<button type="button" class="btn btn-primary" (click)="test()">API測試</button>

4.點擊後成功進入後端API的中斷點了!到這裡已經算是成功了一半了。為什麼說是一半呢?因為會有同源政策(CORS)的問題。

同源政策(CORS)簡單來說就是限制限制其他域名存取自身網站的資源,避免被任意網頁讀取其他網站的敏感資料,或是內部前後端分離使用的是不同的域名,這時候就會需要CORS。由於我們前端跟後端的程式分別屬於不同的網域(前:localhost:44389, 後:localhost:4200),所以會有CORS的問題。

我們必須要到WebAPI裡的Program.cs註冊CORS相關服務跟Middleware套用CORS,CORS詳細介紹可以參考CORS 跨來源資源共用 - 我與 ASP.NET Core 3 的 30天

    builder.Services.AddCors(options =>
    {
        options.AddPolicy("allowCors",
        builder =>
        {
            builder.WithOrigins("http://localhost:4200")
              .AllowAnyMethod()
              .AllowAnyHeader()
              .AllowCredentials()
              .SetIsOriginAllowedToAllowWildcardSubdomains();
/*
AllowAnyOrigin  :允許CORS請求從任何源來訪問,這是不安全的
AllowAnyHeader:允許所有的請求頭
AllowCredentials :服務端也需要允許證書。
AllowAnyMethod允許跨域策略允許所有的方法:GET/POST/PUT/DELETE 等方法 如果進行限制需要 AllowAnyMethod("GET","POST") 這樣來進行訪問方法的限制              
*/            

        });
    });
    //套用CORS,要加在UseRouting() & UseAuthorization()之間
    app.UseCors("allowCors");

重新呼叫一次WebAPI,可以看到成功取得API的回傳值了
 


以上就是一個新專案從無到有的建立過程,雖然是沒有紀錄的很詳細,但是主要的流程大致就是這樣,前後端能互相溝通傳遞資料後,其他的就看各為如何自由發揮了。

 

Ref:
1.Angular 全域安裝 vs 區域安裝
2.EF 反向程式碼工具——EF Core Power Tools
3.VS2019 使用EF Core Power Tools 生成Sqlserver的数据库实体类
4..Net Core EF Core Power Tools
5.[.NETCore] 安裝 Entity Framework Core - 使用 EF Core Power Tool
6.菜雞新訓記 (5): 使用 三層式架構 來切分服務的關注點和職責吧
7.CORS 跨來源資源共用 - 我與 ASP.NET Core 3 的 30天