In this article, we’ll implement Asp.Net Core 5.0 Web API CRUD Operations with Angular 11.
Step 1
Let's first open Visual Studio 2019 and from the new project window, select Asp.Net Core Web Application as shown below.
After providing the project name and location a new window will be opened as follows, Select Target Framework. The above steps will create a brand new ASP.NET Core Web API project
Step 2
Let's install Entity Framework Core NuGet packages to interact with the database
Step 3
Create Folder Models and let's add DB model class file,
- using System;
- using System.Collections.Generic;
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
- using System.Linq;
- using System.Threading.Tasks;
-
- namespace InventoryAPI.Models
- {
- public class InventoryDetail
- {
-
- [Key]
- public int InventoryDetailId { get; set; }
-
- [Column(TypeName = "nvarchar(100)")]
- public string ProductName { get; set; }
-
- [Column(TypeName = "nvarchar(12)")]
- public string SKU { get; set; }
-
- [Column(TypeName = "nvarchar(5)")]
- public string ExpirationDate { get; set; }
-
- [Column(TypeName = "nvarchar(3)")]
- public string Quantity { get; set; }
- }
- }
- using Microsoft.EntityFrameworkCore;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
-
- namespace InventoryAPI.Models
- {
- public class InventoryDetailContext:DbContext
- {
- public InventoryDetailContext(DbContextOptions<InventoryDetailContext> options) : base(options)
- {
-
- }
-
- public DbSet<InventoryDetail> InventoryDetails { get; set; }
- }
- }
DB Migration will be done with this InventoryDetailContext. So we have added the DbSet property for the Detail Model class, after migration PaymentDetails table will be created in SQL Server Database.
Into this model class constructor parameter- options, we have to pass which DbProvider (SQL Server, MySQL, PostgreSQL, etc) to use and corresponding DB connection string also. For that, we’ll be using dependency injection in ASP.NET Core with Startup. cs file as below.
- 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.Hosting;
- using Microsoft.Extensions.Logging;
- using Microsoft.OpenApi.Models;
- using InventoryAPI.Models;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
-
-
- namespace InventoryAPI
- {
-
- public class Startup
- {
- public Startup(IConfiguration configuration)
- {
- Configuration = configuration;
- }
-
- public IConfiguration Configuration { get; }
-
-
- public void ConfigureServices(IServiceCollection services)
- {
-
- services.AddControllers();
- services.AddSwaggerGen(c =>
- {
- c.SwaggerDoc("v1", new OpenApiInfo { Title = "InventoryAPI", Version = "v1" });
- });
-
- services.AddDbContext<InventoryDetailContext>(options =>
- options.UseSqlServer(Configuration.GetConnectionString("DevConnection")));
-
- services.AddCors();
- }
-
-
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- app.UseCors(options =>
- options.WithOrigins("http://localhost:4200")
- .AllowAnyMethod()
- .AllowAnyHeader());
-
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- app.UseSwagger();
- app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "PaymentAPI v1"));
- }
-
- app.UseRouting();
-
- app.UseAuthorization();
-
- app.UseEndpoints(endpoints =>
- {
- endpoints.MapControllers();
- });
- }
- }
- }
Step 4
Let's make use of dependency injection for DbContext class, through which SQL Server is set as a DbProvider with a connection string, Now save the connection string in the appsettings.json file using the UATConnection key as follows.
- {
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
- }
- },
- "AllowedHosts": "*",
- "ConnectionStrings": {
- "UATConnection": "Server=.;Database=InventoryDetailDB;Trusted_Connection=True;MultipleActiveResultSets=True;"
- }
- }
Step 5
Select the project from solution explorer, then go to Tools > NuGet Package Manager > Package Manager Console. Then execute the following commands one by one.
- Add-Migration "InitialCreate"
- Update-Database
Step 6
Now let's create API controller right-click on Controllers folder Add > Controller, Select API Controller with actions, using Entity Framework.
Now we have web methods POST, GET, PUT and DELETE for Create, Retrieve, Update and Delete operations respectively. As a constructor parameter we’ve context of the type InventoryDetailContext. The instance/value for this parameter will be passed from dependency injection from StartUp class.
Step 7
Now let's create Angular Project for front-end client-side app
- ng new app_name
- # after project creation.
- # navigate inside project folder
- cd app_name
- # open in vs code
- code .
- # from vs code terminal
- # command to open the app in default web browser
- ng serve --o
Now we have two components, inventroy-details component to show the list of records and it has a child component inventory-detail-form, a form for insert and update operation can be designed.
To create these 2 components, Lets'execute the below commands.
- ng g c inventory-details -s --skipTests
- ng g c inventory-details/payment-detail-form -s --skipTests
For this application, we’ll be using Bootstrap and Font Awesome Icons. so let’s add their stylesheet reference in index.html.
- <!-- Add following stylesheets to <head> tag -->
- <link rel="preload" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" data-rocket-async="style" as="style" onload="this.onload=null;this.rel='stylesheet'" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
- <link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" data-rocket-async="style" as="style" onload="this.onload=null;this.rel='stylesheet'" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />
Step 8
Let's create a modal class for Inventory Details
- ng g class shared/inventory-detail --type=model --skipTests
- export class InventoryDetail {
- InventoryDetailId: number=0;
- ProductName: string='';
- SKU: string='';
- ExpirationDate: string='';
- Quantity: string='';
- }
Step 9
Create service class as below
- ng g s shared/inventory-detail --skipTests
- import { Injectable } from '@angular/core';
- import { InventoryDetail } from './inventory-detail.model';
- import { HttpClient } from "@angular/common/http";
-
- @Injectable({
- providedIn: 'root'
- })
- export class InventoryDetailService {
- constructor(private http: HttpClient) { }
-
- readonly baseURL = 'http://localhost:61236/api/InventoryDetail';
- formData: InventoryDetail= new InventoryDetail();
- list : InventoryDetail[];
-
-
- postnventoryDetail() {
- return this.http.post(this.baseURL, this.formData);
- }
- putInventoryDetail() {
- return this.http.put(`${this.baseURL}/${this.formData.InventoryDetailId}`, this.formData);
- }
- deleteinventoryDetail(id: number) {
- return this.http.delete(`${this.baseURL}/${id}`);
- }
-
- refreshList() {
- this.http.get(this.baseURL)
- .toPromise()
- .then(res =>this.list = res as InventoryDetail[]);
- }
- }
Lets import HttpClient Module in app.Module.ts file
- import { BrowserModule } from '@angular/platform-browser';
- import { NgModule } from '@angular/core';
- import { FormsModule } from "@angular/forms";
- import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
- import { ToastrModule } from 'ngx-toastr';
-
- import { AppComponent } from './app.component';
- import { InventoryDetailsComponent } from './inventory-details/inventory-details.component';
- import { InventoryDetailFormComponent } from './inventory-details/inventory-detail-form/inventory-detail-form.component';
- import { HttpClientModule } from '@angular/common/http';
-
- @NgModule({
- declarations: [
- AppComponent,
- InventoryDetailsComponent,
- InventoryDetailFormComponent
- ],
- imports: [
- BrowserModule,
- FormsModule,
- HttpClientModule,
- BrowserAnimationsModule,
- ToastrModule.forRoot()
- ],
- providers: [],
- bootstrap: [AppComponent]
- })
- export class AppModule { }
Step 10
Create a form for all crud operations inventory-detail-form.component.html
- <form novalidate autocomplete="off" #form="ngForm" (submit)="onSubmit(form)">
- <input type="hidden" name="inventoryDetailId" [value]="service.formData.inventoryDetailId" />
- <div class="form-group">
- <label>Product NAME</label>
- <input class="form-control form-control-lg" placeholder="Full Name" name="ProductName"
- #cardOwnerName="ngModel" [(ngModel)]="service.formData.ProductName"
- required [class.invalid]="ProductName.invalid && ProductName.touched">
- </div>
- <div class="form-group">
- <label>SKU</label>
- <input class="form-control form-control-lg" placeholder="12 Digit SKU Number" name="SKU"
- #cardNumber="ngModel" [(ngModel)]="service.formData.SKU"
- required maxlength="12" minlength="16" [class.invalid]="SKU.invalid && SKU.touched">
- </div>
- <div class="form-row">
- <div class="form-group col-md-6">
- <label>QUANTITY</label>
- <input type="password" class="form-control form-control-lg" placeholder="QUANTITY" name="Quantity"
- #securityCode="ngModel" [(ngModel)]="service.formData.Quantity"
- required maxlength="3" minlength="3" [class.invalid]="Quantity.invalid && Quantity.touched">
- </div>
- <div class="form-group col-md-6">
- <label>Expiry Date</label>
- <input class="form-control form-control-lg" placeholder="MM/YY" name="ExpirationDate"
- #expirationDate="ngModel" [(ngModel)]="service.formData.ExpirationDate"
- required maxlength="5" minlength="5" [class.invalid]="ExpirationDate.invalid && ExpirationDate.touched">
- </div>
- </div>
- <div class="form-group">
- <button class="btn btn-info btn-lg btn-block" type="submit" [disabled]="form.invalid">SUBMIT</button>
- </div>
- </form>
Conclusion
In this article, we discussed how to build an application using .Net core angular 11 and SQL server. I hope you all enjoyed reading this and learned from it. For better understanding download the source code and find all the form validations and CSS.