65.9K
CodeProject 正在变化。 阅读更多。
Home

Angular 7 SPA CRUD 结合 ASP.NET Core 和 Entity Framework Core

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2018 年 11 月 17 日

CPOL

12分钟阅读

viewsIcon

28910

文章介绍 Angular 7、Entity Framework Core 和 .NET Core

大家好,最近 Angular 7 已经发布,让我们一起探索如何使用 Angular 创建 SPA,并以 .NET Core 和 Entity Framework Core 作为后端。

议程

  1. Angular 7
    1. 新功能
    2. Angular CLI 变更
    3. Angular Material 变更
    4. 升级到 Angular 7
  2. 添加新项目
  3. 使用 Angular 7 进行前端设计和实现
    1. 添加组件
    2. 添加模型和配置文件
    3. 添加 Bootstrap 弹出窗口
    4. 添加数据服务
  4. 使用 ASP.NET Core 和 Entity Framework Core 进行后端 Web API 开发
    1. 设置 .NET Core 项目
    2. 设置 Entity Framework Core
    3. 设置 CORS 以允许跨域资源共享。
  5. 本文的未来扩展
  6. 源代码链接

Angular 7

终于,Angular 7 的等待结束了!!这个版本的 Angular 为我们带来了一些令人兴奋的新功能,主要的变化集中在 Angular 核心、CLI 和 Angular Material,让我们一一探索。

Angular 核心变更

Angular 核心中增加的一些新功能可以在这里列出:

  1. 为 CanLoad 接口引入了新的接口 UrlSegment []
  2. 新的接口 DoBootStrap
  3. 增加了新的元素功能 - 支持 Shadow DOM v1 和插槽(slots)
  4. 增加了新的路由功能 - 警告在 Angular Zone 之外触发的导航
  5. 增加了从格式错误的 URL 中恢复的新能力
  6. 增加了对 import 语句中点 (.) 的新编译器支持,并避免 ngc-wrapped 崩溃
  7. 在提取的 XMB 中添加了新的 "original" 占位符值
  8. 更新了依赖项以支持 Typescript 3.1、RxJS 6.3 和 Node 10。

Angular CLI 变更

还记得之前版本的 Angular 项目设置吗?你只需要输入 ng new Project Name,然后 CLI 会在后台进行处理。在 CLI 执行的过程中,我们会看到一些输出和渲染到屏幕上的数据。Angular 7 最酷的功能之一,也是我最喜欢的功能是 Angular CLI Prompts。借助这个功能,我们只需要回答几个问题就可以设置好项目。让我们通过下面的图片快速了解一下如何做到这一点。

Angular Add Project and CLI changes

Angular Material 和 CDK

Angular Material 和 CDK 带来了一些新功能,例如虚拟滚动和拖放。让我们简要了解一下它们:

虚拟滚动

这允许我们利用列表的突出特点来加载和卸载页面上的 DOM 元素。也就是说,如果我们有一个大量的数据,并想在列表中显示它,那么我们就可以利用这个功能。

拖放

拖放功能得到了 CDK 的支持,包括在用户移动项目时自动渲染的功能,以及为列表中的记录或项目传输提供辅助方法。

应用程序性能

一切都围绕着应用程序,Google 投入了大量的精力和引入了一些功能来帮助我们提高性能。第一个是 Bundle Budget,它允许我们设置应用程序包的大小,并在超过限制时发出错误。默认的包预算大小为 2MB,之后可以增加。

接下来是移除 *Pollyfill.ts* 文件,该文件仅在开发期间使用,在生产环境中会自动移除。

升级到 Angular 7

我们有很多人项目是基于旧版本的 Angular 构建的。为了升级旧版本的 Angular,官方网站提供了相关的方法和详细说明,您可以在这里找到。如果我们从 Angular 6 迁移到 Angular 7,以下命令就可以完成工作:

ng update @angular/cli @angular/core

到目前为止,我们已经完成了 Angular 的功能和升级。现在让我们开始实际操作,添加项目。

添加新项目

为了添加 Angular 项目,我们需要一些先决条件来继续本文的学习:

  1. 安装最新的 Node.js,这将安装 NPM(Node 包管理器),然后 NPM 将下载我们应用程序的所有依赖项或包。最新版本的 Node.js 可以在这里找到。
  2. 获取 Angular CLI 在完成 Node.js 和 NPM 的安装后,下一步就是下载 Angular CLI,它将帮助我们快速设置。安装 CLI 需要以下命令:npm install -g @angular/cli
  3. 获取 Visual Studio Code 这是我们将在本文中使用的 IDE,您可以在这里找到最新版本。

创建新项目

现在是时候使用 Angular 7 添加新项目了。为此,让我们按照下图所示的步骤进行操作:

  1. 创建您想保存项目的目录
  2. 使用命令 ng New Angular7CRUDDemo
  3. 选择合适的选项添加路由和 CSS

注意:根据您的机器和网络速度,下载包和准备项目可能需要一些时间。

项目准备好后,我们从文件菜单打开它,可以看到如下的目录结构:

与旧版本的一个区别是添加了 app-routing 文件,该文件是在设置项目时通过 CLI 提示选项添加的。

现在的问题是,我们如何检查我们的项目是否与 Angular 7 兼容?为此,我们需要检查 package.json 文件,其结构如下:
Project structure

当看到高亮部分时,我们可以说当前项目已配置为使用最新版本的 Angular 依赖项。

现在是实际编码时间了。我们将编码部分分为两部分:第一部分是 Angular 7 的 UI,然后是 .NET Core 和 Entity Framework Core 的 Web API 部分。我们先看 UI 部分,然后看 .NET Core 和 Entity Framework Core 的 Web API 部分。

使用 Angular 进行前端设计和实现

我们都知道任何 Angular 应用程序的前端都是由组件组成的。所以让我们看看应用程序的结构是什么样的,在此之前,先了解一下我们将在本文中实现什么。

在这里,我们将添加一个演示应用程序,用于列出、添加、更新和删除员工。为此,我们将有以下目录结构。

以上是应用程序的目录结构。这里我们有三个组件:

  1. Angular-crud.component.ts 这个组件将列出所有员工,并包含其他组件。
  2. employee-add.component.ts 这个组件用于创建员工记录。
  3. app.component.ts App 组件,所有组件都将通过 <router-outlet></router-outlet> 加载。
  4. Employeeupdate.component.ts 这个组件将负责处理员工记录的编辑操作。
  5. DataService.ts 这个服务将使用 Angular 7 中的 HttpClient 存储所有 API 调用(各种 HTTP 方法)。
  6. Data Models 这个文件夹包含 Employee 数据模型,它将作为所有其他模型的基础,以及 config.ts 文件,该文件将存储与配置相关的数据。
  7. 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 的代码及其模板。

代码描述

  1. 以上是 Employee Add Component 的代码,其中包含了应用程序所需的 import 部分。
  2. 在构造函数中,我们注入了数据服务和 Router。
  3. 我们有一个函数 `Register(regForm:NgForm )`。在这里,我们使用模板驱动的方法来添加员工,所以我们声明了一个 NgForm 类型的表单对象。
  4. 在这个方法中,我们订阅了 `Addemployee` 数据服务。成功后,我们将显示一个警报并重定向到 Home Component。
  5. 我们有一个 `TakeHome` 方法,它将发出一个方法来刷新父组件并从那里重新加载数据。在模板中,我们添加了 Form 标签,并将表单命名为 `#empadd`。在这里,在 Form 的 `NgSubmit` 事件中,我们调用 `Register()`,它将提交表单及其值。
  6. 为了验证目的,我们使用了基本的 HTML 验证。
  7. 最后一行是我们为关闭按钮添加的代码,这是一个虚拟代码,将在员工成功添加后在模板中触发。

以上是关于 Add Component 的内容。让我们看看 Update 组件及其模板,它与 Add Component 具有相同的结构和描述。

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>

以上是 employee update component 的代码。这个组件的描述与 Add component 相同。为了清晰起见,让我们看看 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">&times;</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">&times;</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>

代码描述

  1. 我们导入了组件所需的包。
  2. 根据需求声明变量,并在构造函数中导入了 Data service 和 Router。以下是我们获取添加到父组件(即 Employee list component)的子组件引用的内容。
    @ViewChild('empadd') addcomponent: EmployeeAddComponent  
    @ViewChild('regForm') editcomponent: EmployeeupdateComponent
  1. 为什么我们需要这个?让我们看看接下来的两个函数 `loadAddnew()`、`loadAddnewForm()`。我们在这里使用了 `viewChild` 元素,用于重置和设置特定表单的值。
  2. 接下来是 `LoadData()`。它订阅了数据服务中的 get 方法,并将数据分配给我们的 employee list 对象。
  3. 调用 Delete Employee,它从上面的表格中获取 id,然后调用 Data service 中的 delete 服务,如果成功从数据库中删除了 Employee 数据,则显示警报。
  4. 模板代码很简单,显示员工列表,并在代码中添加了 add 和 edit 组件,它们将在弹出窗口中渲染。

以上是应用程序中的组件。让我们继续探讨其余的 UI 和前端部分。

添加模型和配置文件

    export class  Employee{  
       firstname:string;  
       lastname:string ;  
       email:string;  
       gender:number;  
       id:string  
      
    }

这是我们在整个应用程序中用于发送和接收数据的类。

Config.ts

这个类将存储与配置相关的数据。目前,类中只有 App URL,但未来可以添加更多数据。

添加 Bootstrap 弹出窗口

我们使用弹出窗口来显示 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>

在这里,我们使用了普通的弹出窗口代码,并在 modal-body 中渲染了我们的子组件。

添加数据服务

Data service 是我们将服务调用逻辑与应用程序其余部分分离的层。我们的 Data service 如下所示:

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)返回一个 Observable。我们已经导入了顶部的基本 Http 必需项,如 HttpParams 和 HttpClient,它们是 Angular/Common/http 的一部分。

到目前为止,我们已经完成了前端的设计和实现。让我们转向服务器端设置,这是使用 .NET Core 和 Entity Framework Core 完成的,让我们来看看吧。

使用 ASP.NET Core 和 Entity Framework Core 进行后端 Web API 开发

在本节中,让我们探讨用于实现员工 CRUD 操作的 API。本节主要分为四个部分:如何设置 .NET Core 项目、设置 Entity Framework Core,然后是添加 CORS(跨域资源共享)部分,以便允许 Angular 应用程序与服务器通信。

添加 .NET Core Web API 项目

为了添加 .NET Core web api 项目,请遵循以下步骤:

Add 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();  
            }  
        }  
    }

这是我们的 startup 类,我们在其中配置服务并注册服务。

首先,我们需要添加数据库上下文,我们在这里使用 SQL Server 作为数据库。

接下来,我们需要配置 CORS 选项,允许来自 Angular 应用程序的跨域资源共享。除此之外,我们还添加了中间件,这将再次帮助我们解决 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 应用程序时,我们可以看到如下输出:

本文的未来扩展

看到输出后,您可能会想,这些注册和登录按钮在那里做什么?它们是为未来的扩展准备的。我们将拥有什么?

  1. 通过 Facebook、Gmail 和 Twitter 等外部身份验证进行登录和注册
  2. 在 Web API 端使用 Identity server
  3. 为员工添加新模块,让他们可以登录并记录每日工时表
  4. 供管理员跟踪他们的日常活动。如果有人有兴趣,可以为位于以下链接处的项目做出贡献。

源代码链接

以上文章的源代码链接如下:

参考文献

https://angular.io/

© . All rights reserved.