使用ASP.NET Core和Entity Framework Core實現Angular 7 SPA CRUD
目錄
使用ASPE.NET Core和Entity Framework Core的後端Web API開發
你好最近所有的Angular 7都出來了,讓我們探討如何使用angular建立SPA並使用.net核心和實體框架核心作為後端
Angular 7
最終,Angular 7的等待結束了!! 這個版本的Angular給我們帶來了一些令人興奮的功能,主要是Angular核心的變化,CLI和Angular材料,讓我們逐一探索它 。
Angular Core變化
Angular Core中的一些新增功能可以在此處列出
- 引入了新介面——UrlSegment []到CanLoad介面
- 新介面DoBootStrap
- 添加了新元素特性——啟用Shadow DOM v1和插槽
- 添加了新的路由器特性——警告在Angular區域外觸發導航
- 添加了從格式錯誤的網址中恢復的新功能
- 在import語句中添加了一個新的編譯器支援點(
- 在提取的XMB上添加了新的“原始”佔位符值
- 更新的依賴項以支援Typescript 3.1,RxJS 6.3和Node 10。
Angular CLI更改
記住Angular u的早期版本中的Angular專案設定只是輸入ng new Project Name,然後輸入CLI,同時我們可以看到螢幕,其中有一些輸出和一些資料在螢幕上呈現,使用Angular 7即我最喜歡的一個很酷的功能是Angular CLI提示,通過這個功能,我們可以用幾個Answers設定專案。讓我們快速檢查我們如何在下面的影象中執行此操作。
Angular
Angular Material和CDK推出了虛擬滾動和拖放等新特性,讓我們簡單地探討它們
虛擬滾動
這允許我們使用列表的顯著方面來載入和解除安裝頁面中的DOM元素,這意味著如果我們有大量資料,並且我們想要在列表中顯示它,那麼我們可以使用此特性。
拖放
拖放獲得CDK的支援,包括使用者移動專案時自動呈現的功能,以及用於記錄或傳輸列表中專案的幫助方法
應用程式效能
一切都圍繞著應用程式進行,谷歌投入了大量的精力,並引入了一些特性,這將有助於我們提高效能,第一個特性是Bundle Budget,它允許我們設定應用程式包大小,並在超過限制時給出一些錯的Bundle Budget的限制,預設大小將是2 MB,可以在以後增加。
接下來就是刪除Pollyfill.ts檔案,該檔案僅在開發過程中自動從生產中刪除。
升級到Angular 7
我們很多人都把這個專案建立在Angular的舊版本上,為了升級舊版本的Angular,這個官方網站提供了方法和詳細解釋如何做到這一點,你可以在這裡找到它,如果我們正在從Angular 6遷移到Angular 7,以下命令將幫助我們
ng update @angular/cli @angular/core
到目前為止,我們完成了angular特性和升級,現在讓我們有一些實際操作並新增專案。
新增新專案
要新增angular專案,我們有一些先決條件在繼續本文,
- 安裝最新的Node.js,然後安裝NPM(節點包管理器),後者將下載我們應用程式的所有依賴項或包。可以在此處找到最新版本的Node.js.
- 一旦我們完成了Node.js和NPM就獲取Angular CLI,接下來將下載Angular CLI,它將幫助我們快速設定安裝CLI的東西,我們需要按照命令npm install -g @ angular / cli進行
- 獲取Visual Studio Code,這是我們將在本文中使用的IDE,為了安裝它,您可以在此處找到此最新版本。
建立新專案
現在是時候用Angular 7新增新專案了,讓我們按照下圖中的步驟進行操作,
- 建立要儲存專案的目錄
- 使用命令ng New Angular7CRUDDemo
- 選擇適當的選項以新增路由和CSS
注意根據您的機器和Internet速度,下載軟體包可能需要一些時間,專案已準備就緒。
專案準備好後,讓我們從檔案選單中開啟它,我們可以看到如下的目錄結構,
我們從舊版本中可以看到的一個變化是添加了app-routing檔案,該檔案是在設定專案時從CLI提示符選項新增的
現在問題是我們如何檢查我們的專案是否與Angular 7相容,我們需要檢查package. json 檔案,其具有如下結構ng update
當我們看到突出顯示的部分時,我們可以說當前專案被配置為使用最新版本的angular依賴項。
現在實際編碼時我們將編碼部分分為兩部分,第一部分是Angular 7中的UI,然後.net Core和Entity Framework Core 中的Web API部分,首先看到UI部分,然後我們將看到使用.net Core和Entity Framework Core 的Web API部分。
使用Angular的前端設計和實現
眾所周知,前端或任何angular應用程式都由元件組成,所以讓我們先看看應用程式的結構是什麼,然後才能理解我們將在本文中實現的目標。
這裡我們將新增演示應用程式,該應用程式將用於列出、新增更新和刪除員工,為此我們將具有以下目錄結構。
以上是Application的目錄結構,這裡我們有3個元件即
- Angular-crud.component.ts這將是列出所有員工並將持有其他元件的元件
- employee-add.component.ts這將是建立員工記錄的元件
- app.component.ts App元件,其中所有元件將通過<router-outlet> </ router-outlet>載入
- Employeeupdate.component.ts這將負責處理Employee記錄的Edit操作
- DataService.ts這將使用Angular 7中的Httpclient使用各種動詞儲存所有API呼叫
- Data Models 此資料夾包含Employee資料模型,該模型將作為所有資料的基礎,config.ts檔案將儲存配置相關資料
- App-routing.module.ts這是在配置專案時將在應用程式中新增的路由器。
讓我們一個一個地探索這些元件,
程式碼說明
employee-Add.component.ts
import { Component, OnInit,Input, ViewChild, ElementRef, EventEmitter, Output } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Employee } from 'src/Models/Employee';
import { Router } from '@angular/router';
import {EmployeeDataService} from '../DataService/EmployeeDataService'
@Component({
selector: 'app-employee-add',
templateUrl: './employee-add.component.html',
styleUrls: ['./employee-add.component.sass']
})
export class EmployeeAddComponent implements OnInit {
@Input() cleardata: boolean = false;
@Output() nameEvent = new EventEmitter<string>();
objtempemp:Employee;
@Input() objemp :Employee=new Employee();;
@ViewChild('closeBtn') cb: ElementRef;
constructor(private dataservice:EmployeeDataService,private route:Router) {
}
ngOnInit() {
// this.ResetValues();
}
ResetValues(){
}
Register(regForm:NgForm){
this.objtempemp=new Employee();
this.objtempemp.email=regForm.value.email;
this.objtempemp.firstname=regForm.value.firstname;
this.objtempemp.lastname=regForm.value.lastname;
this.objtempemp.gender=regForm.value.gender;
this.dataservice.AddEmployee(this.objtempemp).subscribe(res=>{
alert("Employee Added successfully");
this.TakeHome();
}
)
}
TakeHome(){
this.nameEvent.emit("ccc");
this.cb.nativeElement.click();
this.route.navigateByUrl('');
}
}
Employee-add.component.html
<div class="container" style="border:thin">
<form #empadd='ngForm' (ngSubmit)="Register(empadd)" class="form-horizontal" style="width:50%" >
<div class="form-group" >
<label class="control-label col-sm-2" for="fname" >First Name:</label>
<div class="col-sm-10">
<input style="width:50%" type="text" class="form-control"
width="50%" id="fname" placeholder="Enter first name"
name="firstname" firstname required [(ngModel)]='objemp.firstname' #firstname="ngModel">
<span class="help-bpx" *ngIf="firstname.touched && !firstname.valid ">Required</span>
</div>
</div>
<div class="form-group" >
<label class="control-label col-sm-2" for="email">Last Name:</label>
<div class="col-sm-10">
<input style="width:50%" required type="text" class="form-control" width="50%"
id="lastname" placeholder="Enter Last Name" name="lastname" lastname required [(ngModel)]='objemp.lastname' #lastname="ngModel">
<span class="help-bpx" *ngIf="lastname.touched && !lastname.valid ">Required</span>
</div>
</div>
<div class="form-group" >
<label class="control-label col-sm-2" for="Gender">Gender:</label>
<div class="col-sm-10">
<select name="gender" gender required [(ngModel)]='objemp.gender' #gender="ngModel">
<option value="0" selected disabled>Please Select</option>
<option value="1">Male</option>
<option value="2">Female</option>
<span class="help-bpx" *ngIf="gender.touched && !gender.valid ">required</span>
</select>
</div>
</div>
<div class="form-group" >
<label class="control-label col-sm-2" for="email">Email:</label>
<div class="col-sm-10">
<input #email="ngModel" style="width:50%" type="email" [(ngModel)]='objemp.email' class="form-control" width="50%" id="email" placeholder="Enter email" name="email">
<span class="help-bpx" *ngIf="email.touched && !email.valid ">**</span>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button id="btnsubmit" type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
<button style="display:none" type="button" #closeBtn class="btn btn-default" data-dismiss="modal">Close</button>
以上是Employee Add Component的程式碼及其模板。
程式碼說明
- 以上是Employee的Add Component的程式碼,我們有這個應用程式所需的匯入部分。
- 在Constructor中,我們注入了資料服務和Router
- 我們有一個函式Register(regForm:NgForm )在這裡我們使用模板驅動的方法來新增員工,所以我們已經聲明瞭型別的表單物件NgForm
- 在此方法中,我們在此成功訂閱了Addemployee資料服務,我們將顯示警報並將路由重定向到Home Component
- 我們有TakeHomeMethod,其會發出重新整理父元件的方法並從那裡重新載入資料。在模板中,我們添加了Form標籤,並將表單命名為#empadd,在此我們呼叫的Form的NgSubmit事件中的Register(),它將提交表單及其值。
- 出於驗證目的,我們使用基本的HTML驗證
- 最後一行我們添加了關閉按鈕的程式碼,它是一個虛擬程式碼,當成功新增Employee時,它將在模板中觸發。
這是關於新增元件,我們可以看到更新元件的模板,該模板具有與新增元件相同的結構和描述。
employeeupdate.component.ts
import { Component, OnInit, ViewChild, Input, EventEmitter, Output, ElementRef } from '@angular/core';
import { EmployeeDataService } from '../DataService/EmployeeDataService';
import { Router } from '@angular/router';
import { NgForm } from '@angular/forms';
import { Employee } from 'src/Models/Employee';
@Component({
selector: 'app-employeeupdate',
templateUrl: './employeeupdate.component.html',
styleUrls: ['./employeeupdate.component.sass']
})
export class EmployeeupdateComponent implements OnInit {
constructor(private dataservice: EmployeeDataService, private route: Router) {
}
@Output() nameEvent = new EventEmitter<string>();
@ViewChild('closeBtn') cb: ElementRef;
ngOnInit() {
}
@Input() reset: boolean = false;
@ViewChild('regForm') myForm: NgForm;
@Input() isReset: boolean = false;
objtempemp: Employee;
@Input() objemp: Employee = new Employee();
EditEmployee(regForm: NgForm) {
this.dataservice.EditEmployee(this.objemp).subscribe(res => {
alert("Employee updated successfully");
this.nameEvent.emit("ccc");
this.cb.nativeElement.click();
},
}
}
employeeupdate.component.html
<div class="container" style="border:thin">
<form #EditForm='ngForm' name="editform" (ngSubmit)="EditEmployee(EditForm)" class="form-horizontal" style="width:50%">
<div class="form-group">
<label class="control-label col-sm-2" for="fname">First Name:</label>
<div class="col-sm-10">
<input style="width:50%" type="text" class="form-control" width="50%" id="fname" placeholder="Enter first name"
name="firstname" firstname required [(ngModel)]='objemp.firstname' #firstname="ngModel">
<span class="help-bpx" *ngIf="firstname.touched && !firstname.valid ">Required</span>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="email">Last Name:</label>
<div class="col-sm-10">
<input style="width:50%" required type="text" class="form-control" width="50%" id="lastname" placeholder="Enter Last Name"
name="lastname" lastname required [(ngModel)]='objemp.lastname' #lastname="ngModel">
<span class="help-bpx" *ngIf="lastname.touched && !lastname.valid ">Required</span>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="Gender">Gender:</label>
<div class="col-sm-10">
<select name="gender" gender required [(ngModel)]='objemp.gender' #gender="ngModel">
<option value="0" selected disabled>Please Select</option>
<option value="1">Male</option>
<option value="2">Female</option>
<span class="help-bpx" *ngIf="gender.touched && !gender.valid ">required</span>
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="email">Email:</label>
<div class="col-sm-10">
<input #email="ngModel" style="width:50%" type="email" [(ngModel)]='objemp.email' class="form-control" width="50%"
id="email" placeholder="Enter email" name="email">
<span class="help-bpx" *ngIf="email.touched && !email.valid ">**</span>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
<button style="display:none" type="button" #closeBtn class="btn btn-default" data-dismiss="modal">Close</button>
以上是此元件的員工更新元件描述的程式碼與新增元件的相同。讓我們探索List元件以獲得清晰度
Employeelist.component.ts
import { Component, OnInit, ViewChild } from '@angular/core';
import { EmployeeAddComponent } from '../employee-add/employee-add.component';
import { EmployeeDataService } from '../DataService/EmployeeDataService'
import { Employee } from 'src/Models/Employee'
import { Router } from '@angular/router';
import { EmployeeupdateComponent } from '../employeeupdate/employeeupdate.component';
@Component({
selector: 'app-angular-crud',
templateUrl: './angular-crud.component.html',
styleUrls: ['./angular-crud.component.sass']
})
export class AngularCRUDComponent implements OnInit {
emplist: Employee[];
dataavailbale: Boolean = false;
tempemp: Employee
constructor(private dataservce: EmployeeDataService, private route: Router) {
}
ngOnInit() {
this.LoadData();
}
LoadData() {
this.dataservce.getEmployee().subscribe((tempdate) => {
this.emplist = tempdate;
console.log(this.emplist);
if (this.emplist.length > 0) {
this.dataavailbale = true;
}
else {
this.dataavailbale = false;
}
}
)
, err => {
console.log(err);
}
}
deleteconfirmation(id: string) {
if (confirm("Are you sure you want to delete this ?")) {
this.tempemp = new Employee();
this.tempemp.id = id;
this.dataservce.DeleteEmployee(this.tempemp).subscribe(res => {
alert("Deleted successfully !!!");
this.LoadData();
})
}
}
@ViewChild('empadd') addcomponent: EmployeeAddComponent
@ViewChild('regForm') editcomponent: EmployeeupdateComponent
loadAddnew() {
this.addcomponent.objemp.email = ""
this.addcomponent.objemp.firstname = ""
this.addcomponent.objemp.lastname = ""
this.addcomponent.objemp.id = ""
this.addcomponent.objemp.gender = 0
}
loadnewForm(id: string, email: string, firstname: string, lastname: string, gender: number) {
console.log(gender);
this.editcomponent.objemp.email = email
this.editcomponent.objemp.firstname = firstname
this.editcomponent.objemp.lastname = lastname
this.editcomponent.objemp.id = id
this.editcomponent.objemp.gender = gender
}
RefreshData() {
this.LoadData();
}
}
EmployeeList.html
<div class="container">
<input type="button" class="btn btn-primary" (click)="loadAddnew()" data-toggle="modal" data-target="#myModal" value="Create New">
<hr>
<div *ngIf="!dataavailbale">
<h4> No Employee Data is present Click Add new to add Data.</h4>
</div>
<table class="table" *ngIf="dataavailbale">
<thead>
<tr>
<th scope="col">Sr.No</th>
<th scope="col">First name</th>
<th scope="col">Last Name</th>
<th scope="col">Email</th>
<th scope="col">Gender</th>
<th scope="col" style="align-content: center">Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let e of emplist let i = index ">
<td scope="col">{{i+1}}</td>
<td scope="col">{{e.fname}}</td>
<td scope="col">{{e.lname}}</td>
<td scope="col">{{e.email}}</td>
<td scope="col">{{e.gender=="1"?'Male':'Female'}}</td>
<td style="display:none">{{e.id}}</td>
<td scope="col">
<button type="button" class="btn btn-default btn-primary" (click)="loadnewForm(e.id,e.email,e.fname,e.lname,e.gender)"
data-toggle="modal" data-target="#myModaledit">
<span class="glyphicon glyphicon-edit"></span> Edit
</button>
|
<button type="button" class="btn btn-default btn-danger" (click)="deleteconfirmation(e.id)">
<span class="glyphicon glyphicon-trash"></span> Delete
</button>
</td>
</tr>
</tbody>
</table>
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-primary">Employee Add</h4>
</div>
<div class="modal-body">
<app-employee-add #empadd (nameEvent)="RefreshData($event)"></app-employee-add>
</div>
<div class="modal-footer">
<button type="button" #closeBtn class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="myModaledit" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Edit</h4>
</div>
<div class="modal-body">
<app-employeeupdate (nameEvent)="RefreshData($event)" [isReset]="resetForm" #regForm></app-employeeupdate>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
程式碼說明
- 我們正在做一些我們在元件中需要的匯入包
- 根據需求在建構函式中宣告的變數,我們已經匯入了Data服務和Router Following,這些內容使我們獲得了父元件中新增的子元件的引用,即Employee列表元件
@ViewChild('empadd') addcomponent: EmployeeAddComponent
@ViewChild('regForm') editcomponent: EmployeeupdateComponent
- 為什麼我們需要這個?讓我們看看接下來的兩個函式loadAddnew(),loadAddnewForm(),我們正在使用這兩個viewChild元素來重置和設定特定表單的值
- 我們接下來要做的是LoadData(),它在資料服務中訂閱get,資料服務中的方法,並將資料分配給我們擁有的員工列表物件
- 呼叫Delete Employee,它從上面的表中獲取id,然後從Data服務呼叫delete服務,然後在成功從資料庫中刪除Employee Data時顯示alert。
- 模板程式碼很簡單顯示了員工的列表,並在程式碼中添加了新增和編輯元件,這些元件將在Popup中呈現
這是應用程式中的元件,為此可以探索其餘的UI和前端部分。
新增模型和配置檔案
export class Employee{
firstname:string;
lastname:string ;
email:string;
gender:number;
id:string
}
這是我們將在整個應用程式中用於傳送和接收資料的類
Config.ts
此類將保留配置相關資料,現在我們在類中只有App URL,但我們可以在此處獲得其餘資料。
新增Bootstrap彈出視窗
我們使用Popups來顯示Add和Edit表單,這樣我們就可以在Employee List元件模板中定義程式碼了。
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-primary">Employee Add</h4>
</div>
<div class="modal-body">
<app-employee-add #empadd (nameEvent)="RefreshData($event)"></app-employee-add>
</div>
<div class="modal-footer">
<button type="button" #closeBtn class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
在這裡我們使用了普通的Popup程式碼,在模態體內我們渲染了子元件。
新增資料服務
資料服務是我們將服務呼叫邏輯與應用程式的其餘部分分開的層。我們的資料服務如下所示,
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Employee } from 'src/Models/Employee'
import { ROOT_URL } from 'src/Models/Config'
import { Observable } from 'rxjs';
@Injectable()
export class EmployeeDataService {
employees: Observable<Employee[]>;
newemployee: Employee;
constructor(private http: HttpClient) {
}
getEmployee() {
return this.http.get<Employee[]>(ROOT_URL + 'Employees');
}
AddEmployee(emp: Employee) {
const headers = new HttpHeaders().set('content-type', 'application/json');
var body = {
Fname: emp.firstname, Lname: emp.lastname, Email: emp.email, gender: emp.gender
}
console.log(ROOT_URL);
return this.http.post<Employee>(ROOT_URL + '/Employees', body, { headers });
}
///
EditEmployee(emp: Employee) {
console.log(emp);
const params = new HttpParams().set('ID', emp.id);
const headers = new HttpHeaders().set('content-type', 'application/json');
var body = {
Fname: emp.firstname, Lname: emp.lastname, Email: emp.email, ID: emp.id
, gender: emp.gender
}
return this.http.put<Employee>(ROOT_URL + 'Employees/' + emp.id, body, { headers, params })
}
DeleteEmployee(emp: Employee) {
const params = new HttpParams().set('ID', emp.id);
const headers = new HttpHeaders().set('content-type', 'application/json');
var body = {
Fname: emp.firstname, Lname: emp.lastname, Email: emp.email, ID: emp.id
}
return this.http.delete<Employee>(ROOT_URL + '/Employees/' + emp.id)
}
}
在這篇文章中,我們擁有所有使用Httpclient並返回基本http動詞(如Get、Put、Post和delete)的可觀察值的方法,我們在頂部匯入了基本的Http要素,如HttpParams和HttpClient,它們是是Angular / Common / http的一部分
到目前為止,我們已經完成了前端設計和實現,讓我們轉移到伺服器端設定,它是使用.NET Core和Entity Framework Core完成的,所以我們來看看吧
使用ASPE.NET Core和Entity Framework Core的後端Web API開發
在本節中,讓我們探討我們用於實現員工CRUD操作的API,這部分可以分為4個部分,主要是我們如何設定.NET Core專案然後設定實體框架核心,然後新增CORS(跨源資源共享)部分,以便允許angular應用程式與伺服器通訊。
新增.NET Core Web API專案
要新增.NET核心web api專案,請按照以下步驟操作,
完成新增專案後,讓我們轉向新增專案並進行必要的更改
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Angular7DemoServices;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Angular6DemoServices
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddCors();
services.AddDbContext<AppDbContext>(opt => opt.UseSqlServer(@"Your connection string"));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMiddleware();
app.UseCors();
app.UseMvc();
}
}
}
這是我們的啟動類,我們在其中配置服務和註冊服務
首先是新增資料庫上下文,我們將SQL server用作資料庫
接下來我們需要做的是配置CORS選項,我們允許從Angular應用程式共享Cross origin資源。除此之外,我們還添加了中介軟體,它將再次幫助我們解決CORS問題。中介軟體程式碼如下所示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
namespace Angular7DemoServices
{
// You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
public class CorsMiddleware
{
private readonly RequestDelegate _next;
public CorsMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext httpContext)
{
httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept");
httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
return _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<CorsMiddleware>();
}
}
}
這將是中介軟體,它將在請求響應和API中新增所需的頭。其餘部分只是簡單的CRUD操作,我們很熟悉,如果不熟悉,我們可以在Github上找到它,其地址將在下面共享
因此,當我們執行Web API和Angular應用程式時,我們可以看到如下輸出,
原始碼連結
以下是上述文章的原始碼連結
參考
原文地址:https://www.codeproject.com/Articles/1267254/Angular-7-SPA-CRUD-With-ASP-NET-Core-And-Entity-Fr