In this article, we will create a .NET 5 Web API and Angular application to perform CRUD operations with the help of Entity Framework Core.
To demonstrate CRUD operation with .NET 5 Web API, we will use sample Product data.
What is .NET Web API?
.Net Web API is a framework for building, and consuming HTTP-based service. The advantage of Web API is that it can be consumed by a wide range of clients like a web browser and mobile applications.
Pre-requisites
- .NET 5 Framework
- Visual Studio 2019
- Angular 7 and above
- SQL Server 2008 and above
Database Design
Create Table
CREATE TABLE [dbo].[Product_Master](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ProductName] [varchar](250) NULL,
[ProductDescription] [varchar](250) NULL,
[ProductCost] [decimal](18, 0) NULL,
[Stock] [int] NULL,
CONSTRAINT [PK_Product_Master] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Add few records
What is .NET 5?
Dot Net 5 or .NET 5 is one of the major releases after .NET Core 3.1. It was released in November 2020.
Microsoft, dropped the word “Core” from the name to indicate that this is the future of .NET. It supports more platforms and apps than .NET Core and .NET Framework.
Create .NET 5 API Project in Visual Studio 2019
Let’s create a .NET 5 Web API project in Visual Studio 2019. There is no big issue in creating a project in Visual Studio 2019. Follow the below steps –
- Open Visual Studio 2019.
- Click on Create a new Project.
- Select ASP.Net Core Web API from the Project template. Click Next
- Give a name to your project. Click Next.
- Select .NET 5.0 as the Target framework.
How to create .NET 5 Web API in Visual Studio 2019?
Add a Model class to your project.
Model Class (Product.cs
)
public class Product
{
[Key]
public int Id { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public decimal ProductCost { get; set; }
public int Stock { get; set; }
}
Install packages related to Entity Framework
You need to install a few packages. You can do this either via the Packager Manager console or from the Nuget Packager Manager Wizard.
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
(Install-Package Microsoft.EntityFrameworkCore.SqlServer)Microsoft.EntityFrameworkCore.Tools
(Install-Package Microsoft.EntityFrameworkCore.Tools)
Add Data Context Class
MyDataContext.cs File
public class MyDataContext:DbContext
{
public MyDataContext(DbContextOptions<MyDataContext> options) : base(options)
{
}
public DbSet<Product> Products { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().ToTable("Product_Master");
}
}
Add Database Connection String
In appsettings.json
file, add a connection string
"ConnectionStrings": {
"DefaultConnection": "Data Source=localhost\\sqlexpress;Initial Catalog=ProductDataBase;Trusted_Connection=True;"
}
Get Database Connection String in Startup.cs file
Add the below line to the ConfigureServices()
method in startup.cs
file:
services.AddDbContext<MyDataContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
Allow Origins and Header
Add the below line to the Configure()
method in startup.cs
file. This will help us to avoid a ‘CORS’ related issue in the browser.
app.UseCors(options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
Add a Controller class to your project. (ProductController.cs
)
public class ProductController : ControllerBase
{
private readonly MyDataContext _context;
public ProductController(MyDataContext context)
{
_context = context;
}
[HttpGet]
[Route("List")]
public async Task<ActionResult<IEnumerable<Product>>> Get()
{
return await _context.Products.ToListAsync();
}
[HttpGet]
[Route("Details")]
public async Task<ActionResult<Product>> Get(int id)
{
var data = await _context.Products.FindAsync(id);
return data;
}
[HttpPost]
//public async void Post(Product product)
[Route("CreateRecord")]
public async Task<ActionResult<Product>> POST(Product product)
{
_context.Products.Add(product);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
}
// PUT api/<ProductController>/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
[HttpPost]
[Route("DeleteProduct")]
public async Task<ActionResult<IEnumerable<Product>>> Delete(int id)
{
var product = await _context.Products.FindAsync(id);
if (product == null)
{
return NotFound();
}
_context.Products.Remove(product);
await _context.SaveChangesAsync();
return await _context.Products.ToListAsync();
}
[HttpPost]
[Route("UpdateProduct")]
public async Task<ActionResult<IEnumerable<Product>>> Update(int id, Product product)
{
if (id != product.Id)
{
return BadRequest();
}
var productData = await _context.Products.FindAsync(id);
if (productData == null)
{
return NotFound();
}
productData.ProductCost = product.ProductCost;
productData.ProductDescription = product.ProductDescription;
productData.ProductName = product.ProductName;
productData.Stock = product.Stock;
await _context.SaveChangesAsync();
return await _context.Products.ToListAsync();
}
}
Test .NET 5 Web API with POSTMAN Tool
Once you have created .NET 5 Web API, you need to test it before you integrate it with an Angular application.
Create Angular Project
Now, create an Angular project with the below command.
ng new Net5Demo
Model File
export class Products {
id: number;
productName: string;
productCost: number;
productDescription: string;
stock: number;
}
Service File
Add a service file with the below command
ng g s net5-service
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Products } from './Products';
@Injectable({
providedIn: 'root'
})
export class Net5ServiceService {
url = 'https://localhost:44303/api/Product/';
constructor(private http: HttpClient) { }
getProductList(): Observable<Products[]> {
return this.http.get<Products[]>(this.url + 'List');
}
postProductData(productData: Products): Observable<Products> {
const httpHeaders = { headers:new HttpHeaders({'Content-Type': 'application/json'}) };
return this.http.post<Products>(this.url + 'CreateRecord', productData, httpHeaders);
}
updateProduct(product: Products): Observable<Products> {
const httpHeaders = { headers:new HttpHeaders({'Content-Type': 'application/json'}) };
return this.http.post<Products>(this.url + 'UpdateProduct?id=' + product.id, product, httpHeaders);
}
deleteProductById(id: number): Observable<number> {
return this.http.post<number>(this.url + 'DeleteProduct?id=' + id, null);
}
getProductDetailsById(id: string): Observable<Products> {
return this.http.get<Products>(this.url + 'Details?id=' + id);
}
}
Component file
Let’s create a component file with the below command. (net5-apicall
is the component file)
ng g c net5-apicall
<form class="form-horizontal" [formGroup]="productForm">
<h1>Welcome to Angular CRUD with .NET 5</h1>
<div class="form-group">
<label class="control-label col-sm-2" for="pwd">Name of Product :</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="txtProductName" formControlName="productName"
placeholder="Name of Product">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="pwd">Cost of Product :</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="txtProductCost" formControlName="productCost" placeholder="Cost of Product">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="pwd">Product Description :</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="txtProductDescription" formControlName="productDescription"
placeholder="Product Description">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="pwd"># of Stock Available :</label>
<div class="col-sm-2">
<input type="text" class="form-control" id="txtStock" formControlName="stock" placeholder="Stock Available">
</div>
</div>
<div class="form-group">
<div class="container">
<div class="row">
<div class="col-sm">
<button type="submit" class="btn btn-primary" (click)="PostProduct(productForm.value)">Submit</button>
</div>
<div class="col-sm">
<button type="submit" class="btn btn-primary" (click)="UpdateProduct(productForm.value)">Update</button>
</div>
</div>
</div>
</div>
<div>
<div class="alert alert-info"><b>Product List</b></div>
<div class="table-responsive">
<table class="table">
<tr>
<th>Product Name</th>
<th>Cost</th>
<th># of Stock</th>
<th>Description</th>
<th>Action</th>
</tr>
<tr *ngFor="let prd of ProductList | async">
<td>{{prd.productName}}</td>
<td>{{prd.productCost}}</td>
<td>{{prd.stock}}</td>
<td>{{prd.productDescription}}</td>
<td><button type="button" matTooltip="Click Edit Button" (click)='ProductDetailsToEdit(prd.id)'>Edit</button>
|
<button type="button" matTooltip="Click Delete Button" (click)="DeleteProduct(prd.id)">Delete</button>
</td>
</tr>
</table>
</div>
</div>
</form>
Component Type Script File
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { Net5ServiceService } from '../net5-service.service';
import { Products } from '../Products';
@Component({
selector: 'app-net5-apicall',
templateUrl: './net5-apicall.component.html',
styleUrls: ['./net5-apicall.component.css']
})
export class Net5APICallComponent implements OnInit {
ProductList: Observable<Products[]>;
ProductList1: Observable<Products[]>;
productForm: any;
massage = "";
prodCategory = "";
productId = 0;
constructor(private formbulider: FormBuilder, private httpClient: HttpClient, private productService: Net5ServiceService) { }
ngOnInit() {
this.prodCategory = "0";
this.productForm = this.formbulider.group({
productName: ['', [Validators.required]],
productCost: ['', [Validators.required]],
productDescription: ['', [Validators.required]],
stock: ['', [Validators.required]]
});
this.getProductList();
}
getProductList() {
this.ProductList1 = this.productService.getProductList();
this.ProductList = this.ProductList1;
}
PostProduct(product: Products) {
debugger;
const product_Master = this.productForm.value;
this.productService.postProductData(product_Master).subscribe(
() => {
this.massage = 'Data Saved Successfully';
this.getProductList();
}
);
}
ProductDetailsToEdit(id: string) {
debugger;
this.productService.getProductDetailsById(id).subscribe(productResult => {
this.productId = productResult.id;
this.productForm.controls['productName'].setValue(productResult.productName);
this.productForm.controls['productCost'].setValue(productResult.productCost);
this.productForm.controls['productDescription'].setValue(productResult.productDescription);
this.productForm.controls['stock'].setValue(productResult.stock);
// this.productForm.controls['product_category'].setValue(productResult.productCost);
});
}
UpdateProduct(product: Products) {
debugger;
product.id = this.productId;
const product_Master = this.productForm.value;
this.productService.updateProduct(product_Master).subscribe(() => {
this.massage = 'Record Updated Successfully';
this.getProductList();
});
}
DeleteProduct(id: number) {
if (confirm('Do you want to delete this product?')) {
this.productService.deleteProductById(id).subscribe(() => {
this.getProductList();
});
}
}
}
Add Routing
const routes: Routes = [
{path: 'crud', component: Net5APICallComponent}
];
Import HttpClientModule, FormsModule and ReactiveFormsModule in app.module.ts file
import {HttpClientModule} from '@angular/common/http';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
Add modules in the imports array in app.module.ts the file
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
FormsModule,
ReactiveFormsModule
],
Change app.component.html file
Remove everything from the app.component.html file and put it below the line.
<router-outlet></router-outlet>
Run your Project
Compile your project with the below command
ng serve
Your screen should look like this.
Watch this Video which demonstrates the .NET 5 API CRUD with Angular
This demonstration will work with .NET Core 2.1 and .NET Core 3.1 as well.
Hope you like this article. Please share your feedback in the comment box below.
You may read this article – ASP.Net Core Interview Questions and Answers