.NET & Angular Archives - Tech Insights https://reactconf.org/category/net-angular/ Unveiling Tomorrow's Tech Today, Where Innovation Meets Insight Wed, 18 Oct 2023 12:14:27 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.2 https://i0.wp.com/reactconf.org/wp-content/uploads/2023/11/cropped-reactconf.png?fit=32%2C32&ssl=1 .NET & Angular Archives - Tech Insights https://reactconf.org/category/net-angular/ 32 32 230003556 How to Create CRUD operation using Angular and ASP.NET Core Web API https://reactconf.org/how-to-create-crud-operation-using-angular-and-asp-net-core-web-api/ https://reactconf.org/how-to-create-crud-operation-using-angular-and-asp-net-core-web-api/#respond Wed, 18 Oct 2023 12:14:27 +0000 https://labpys.com/?p=1481 In this article, we will learn How to Create CRUD operation using Angular and ASP.NET Core Web API. To demonstrate the topic, we will build a project from scratch. We …

The post How to Create CRUD operation using Angular and ASP.NET Core Web API appeared first on Tech Insights.

]]>
In this article, we will learn How to Create CRUD operation using Angular and ASP.NET Core Web API. To demonstrate the topic, we will build a project from scratch.

We will take a systematic step-by-step approach, applying the principles of clean architecture, to develop CRUD operation using Angular and ASP.NET Core Web API

Prerequisites

ASP.NET Web API Project

Create Web API

dotnet new project_Name

Create Classlib project

# Create Domain layer
dotnet new classlib -n Domain
# Create Application layer
dotnet new classlib -n Application
# Create Infrastructure layer
dotnet new classlib -n Infrastructure

Install Packages

Install packages in the Infrastructure project

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.Sqlite
  • Microsoft.EntityFrameworkCore.Tools

Reference the projects

Now that we understand the principles of Clean Architecture, let’s see how we can reference it in an ASP.NET Core Web API project

Application Layer

  <ItemGroup>
    <ProjectReference Include="..\Domain\Domain.csproj" />
  </ItemGroup>

Infrastructure Layer

   <ItemGroup>
    <ProjectReference Include="..\Domain\Domain.csproj" />
    <ProjectReference Include="..\Application\Application.csproj" />
  </ItemGroup>

Web API

 <ItemGroup>
    <ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
  </ItemGroup>

Create Entities in the Domain Layer

path:/Domain/Entities

Employee.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Domain.Entities
{
    public class Employee : BaseEntity
    {        
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Street {get;set;}
        public string City { get; set; }
        public string State { get; set; }  
    }
}

BaseEntity.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Domain.Entities
{
    public class BaseEntity
    {
        public BaseEntity()
        {
            
            CreateAt = DateTime.UtcNow;
        }
        public int Id { get; set; }
        public DateTime CreateAt { get; set; }
    }
}

Create an Interface in the Application Layer

path:/Application/Interfaces

IEmployeeRepo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Domain.Entities;
 
namespace Application.Interfaces
{
    public interface IEmployeeRepo
    {
        Task<IReadOnlyList<Employee>> GetEmployeeListAsync();
        Employee GetEmployeeById(int id);
        Employee CreateEmployee(Employee employee);
        Employee UpdateEmployee(Employee employee);
        void DeleteEmployee(int id);

    }
}

Create DB Context, Concrete Class, and Services in the Infrastructure Layer

path:/Infrastructure/Data

AppDbContext.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Domain.Entities;
using Microsoft.EntityFrameworkCore;

namespace Infrastructure.Data
{
    public class AppDbContext : DbContext
    {

        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {
        }
        public DbSet<Employee> Employees { get; set;}
    }
}

path:/Infrastructure/Repository

EmployeeRepository.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Application.Interfaces;
using Domain.Entities;
using Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace Infrastructure.Repository
{
    public class EmployeeRepository : IEmployeeRepo
    {

        private readonly AppDbContext _context;

        public EmployeeRepository(AppDbContext context)
        {
            _context = context;
        }
        public Employee CreateEmployee(Employee employees)
        {
            _context.Employees.Add(employees);
            var result = _context.SaveChangesAsync();
            if (result.IsCompletedSuccessfully) { return employees; }

            return null;
        }

        public Employee GetEmployeeById(int id)
        {
            return _context.Employees.FindAsync(id).Result;
        }

        public async Task<IReadOnlyList<Employee>> GetEmployeeListAsync()
        {
            return await _context.Employees.ToListAsync();

        }

        public Employee UpdateEmployee(Employee employee)
        {
            this._context.Employees.Update(employee);
            _context.SaveChanges();
            return employee;
        }

        public void DeleteEmployee(int id)
        {
            var result = GetEmployeeById(id);
            _context.Employees.Remove(result);
            _context.SaveChanges();

        }
    }
}

path:/Infrastructure/Services

ServicesConfig.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Application.Interfaces;
using Infrastructure.Data;
using Infrastructure.Repository;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Infrastructure.Services
{
    public static class ServicesConfig
    {
        public static IServiceCollection AddApplication(this IServiceCollection services, IConfiguration config)
        {

            services.AddDbContext<AppDbContext>(opt =>
            {
                opt.UseSqlite(config.GetConnectionString("connection"));
            });

            services.AddScoped<IEmployeeRepo, EmployeeRepository>();

           
            return services;
        }
    }
}

Update Program.cs

using Infrastructure.Services;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddApplication(builder.Configuration);
//builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

builder.Services.AddCors(Opt => Opt.AddDefaultPolicy(opt =>
                {
                    opt.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin();
                }));

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();


app.UseAuthorization();

app.MapControllers();
app.UseCors();
app.Run();

Migration

dotnet ef migrations add  initialcreate -p .\Infrastructure\ -s API  -o Migrations

dotnet ef database update -p Infrastructure -s API

Create Account Controller

EmployeeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Application.Interfaces;
using Domain.Entities;
using Microsoft.AspNetCore.Mvc;

namespace API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        private readonly IEmployeeRepo _employeeRepo;


        public EmployeeController(IEmployeeRepo employeeRepo)
        {
            _employeeRepo = employeeRepo;

        }
        [HttpGet]
        public async Task<IReadOnlyList<Employee>> GetEmployees()
        {

            return await this._employeeRepo.GetEmployeeListAsync();
        }
        [HttpPost]
        public ActionResult EmployeePost(Employee employees)
        {

            var result = _employeeRepo.CreateEmployee(employees);
            return Ok(result);
        }

        [HttpPut]
        public ActionResult EmployeePut(Employee employee)
        {


            var result = _employeeRepo.UpdateEmployee(employee);
            return Ok(result);
        }

        [HttpGet("{id}")]
        public Employee EmployeeGetById(int id)
        {
            var result = this._employeeRepo.GetEmployeeById(id);
            return result;
        }
        [HttpDelete("{id}")]
        public ActionResult DeleteEmployee(int id)
        {
            this._employeeRepo.DeleteEmployee(id);
            return Ok("Employee Deleted");
        }
    }
}

Create Client-side Angular Project

To create the client-side application, we’ll be using Angular. This section will guide you through setting up an Angular project and creating the necessary components.

# Create a client side Application
ng new project_name
# Navigate the inside project folder
cd project_name

# open the VS Code
code .

# Run the App
ng serve

Create Module | Services | Routing | Shared Module

# Create a module
ng   g  m employee/employee --flat

# Create a Routing
ng   g  m employee/employee-routing --flat

# Create a Service
 ng   g  s employee/employee  --flat
# Shared module
Employee.ts

Update Routing

import { NgModule, createComponent } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule   } from '@angular/router';
import { ReadComponent } from './read/read.component';
import { UpdateComponent } from './update/update.component';
import { DeleteComponent } from './delete/delete.component';
import { CreateComponent } from './create/create.component';


const routes : Routes=[

  {path:'', component:ReadComponent},
  {path:'Create', component:CreateComponent}, 
  {path:'update/:id', component:UpdateComponent},
  {path:'delete/:id', component:DeleteComponent},

]

@NgModule({
  declarations: [],
  imports: [
    RouterModule.forChild(routes),
    CommonModule
  ],
  exports:[
    RouterModule
  ]
})
export class EmployeeRoutingModule { }

Update Module

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CreateComponent } from './create/create.component';
import { UpdateComponent } from './update/update.component';
import { ReadComponent } from './read/read.component';
import { DeleteComponent } from './delete/delete.component';
import { EmployeeRoutingModule } from './employee-routing.module';
import { ReactiveFormsModule } from '@angular/forms';



@NgModule({
  declarations: [
    CreateComponent,
    UpdateComponent,
    ReadComponent,
    DeleteComponent
  ],
  imports: [
    EmployeeRoutingModule,
    ReactiveFormsModule,
    CommonModule
  ]
})
export class EmployeeModule { }

Create Shared Module

Employee.ts

export interface Employee {
    id : number,
    firstName : string,
    lastName : string,
    street : string,
    city : string,
    state : string,
    createAt : Date
}

Update Service

import { Injectable } from '@angular/core';
import { Router, Routes } from '@angular/router';
import { HttpClient } from '@angular/common/http'
import { Employee } from '../shared/modules/Employee';
import { map } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class EmployeeService {
  baseUrl = 'https://localhost:8080/api';
   
  constructor(private http : HttpClient ,private router : Router ) { }

  CreateEmployee(values:any){
      return this.http.post<Employee>(this.baseUrl + '/Employee/',values).pipe(
        map(employee=> {
          alert("Employee Created Successfully...!" + employee);
        })
      )
  }

  GetEmployee(){
    return this.http.get<Employee>(this.baseUrl + '/Employee/')
  }

  GetEmployeeById(id:number){
    return this.http.get<Employee>(this.baseUrl + '/Employee/'+ id)
  }

  UpdateEmployee(values:any){

    return this.http.put<Employee>(this.baseUrl + '/Employee/', values).pipe(
      map(emp=>{
        alert("Employee Updated Successfully...!" + emp);
      })
    )
  }
  RemoveEmployee(id:number){
    return this.http.delete(this.baseUrl + '/Employee/' + id);

  }
}

Create Component

# Create a component
ng  g c Employee/Read --skip-tests
ng  g c Employee/Create--skip-tests
ng  g c Employee/Update --skip-tests
ng  g c Employee/Delete --skip-tests

Update Read Component

read.component.ts

import { Component, OnInit } from '@angular/core';
import { EmployeeService } from '../employee.service';
import { ActivatedRoute } from '@angular/router';
import { Employee } from 'src/app/shared/modules/Employee';

@Component({
  selector: 'app-read',
  templateUrl: './read.component.html',
  styleUrls: ['./read.component.scss']
})
export class ReadComponent implements OnInit {
  employee? :any;

 constructor(private employeeServices: EmployeeService, private router:ActivatedRoute){}

  ngOnInit(): void {
    this.loadEmployee();
  }

  loadEmployee(){
    this.employeeServices.GetEmployee().subscribe({
       next : emp => this.employee=emp,
       error: error=> alert(error)       
    });
  }
}

read.component.html

<div>
<table class="table table-success  table-striped">
<thead>
    <tr>
    <th>Id</th>
    <th>First Name</th>
    <th>Last Name</th>
    <th>Street</th>
    <th>City</th>
    <th>State</th>
    <th>Created At</th>
    <th>Action</th>
    </tr>
</thead>
<tbody *ngFor="let emp of employee">
    <tr>
        <td>{{emp.id}}</td>
        <td>{{emp.firstName}}</td>
        <td>{{emp.lastName}}</td>
        <td>{{emp.street}}</td>
        <td>{{emp.city}}</td>
        <td>{{emp.state}}</td>
        <td>{{emp.createAt}}</td>
        <td>
            <h5 class="mb-0">
                <a routerLink="/delete/{{emp.id}}" class="text-dark text-decoration-none">
                    <span class="fa fa-trash"></span> 
                </a>
            </h5>
        
            <h5 class="mb-0">
                <a routerLink="/update/{{emp.id}}" class="text-dark text-decoration-none">
            <span class="fa fa-edit"></span>
                   
                </a>
            </h5>
        </td>
    </tr>
</table>
</div>

Update Create Component

create.component.ts

import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { EmployeeService } from '../employee.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-create',
  templateUrl: './create.component.html',
  styleUrls: ['./create.component.scss']
})
export class CreateComponent {
  title : string ='Employee Registeration Form';

  EmpForm = new FormGroup({
    firstName : new FormControl('',Validators.required),
    lastName: new FormControl('',Validators.required),
    street: new FormControl('',Validators.required),
    city: new FormControl('',Validators.required),
    state: new FormControl('',Validators.required) 
  });

   constructor(private employeeService: EmployeeService, private router: Router){}

  onSubmit(){
    this.employeeService.CreateEmployee(this.EmpForm.value).subscribe({
      next:()=> this.router.navigateByUrl('/'),
      error:()=> alert("Please check ...!") 
    })
    
  }
}

create.component.html

<div class="d-flex justify-content-center mt-5">
    <div class="col-3">
        <form [formGroup]="EmpForm"  (ngSubmit)="onSubmit()">
            <div class="text-center mb-4">
                <h1 class="mb-3">
                    Employee
                </h1>
            </div>
            <div class="form-floating mb-3">
                <input type="firstName" formControlName="firstName"  class="form-control" id="floatingInput" placeholder="first Name">
                <label for="floatingInput">firstName</label>
              </div>
              <div class="form-floating">
                <input type="lastName" formControlName="lastName" class="form-control" id="floatingPassword" placeholder="last Name">
                <label for="floatingPassword">lastName</label>
              </div>
              <div class="form-floating">
                <input type="street" formControlName="street" class="form-control" id="floatingPassword" placeholder="street">
                <label for="floatingPassword">street</label>
              </div>
              <div class="form-floating">
                <input type="city" formControlName="city" class="form-control" id="floatingPassword" placeholder="city">
                <label for="floatingPassword">city</label>
              </div>
              <div class="form-floating">
                <input type="state" formControlName="state" class="form-control" id="floatingPassword" placeholder="state">
                <label for="floatingPassword">state</label>
              </div>
              <div class="d-grid">
                <button class="btn btn-lg btn-primary mt-3" type="submit">
                     Submit
                </button>
              </div>
        </form>
    </div>
</div>

Update Edit Component

update.component.ts

import { Component, OnInit } from '@angular/core';
import { EmployeeService } from '../employee.service';
import { ActivatedRoute, Router } from '@angular/router';
import { FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-update',
  templateUrl: './update.component.html',
  styleUrls: ['./update.component.scss']
})
export class UpdateComponent implements OnInit{
employee?:any;
id?:any; 



constructor(private employeeService:EmployeeService, private router:ActivatedRoute,private route:Router)
{
  this.id = this.router.snapshot.paramMap.get('id');
}


EmpForm = new FormGroup({
  firstName : new FormControl('',Validators.required),
  lastName: new FormControl('',Validators.required),
  street: new FormControl('',Validators.required),
  city: new FormControl('',Validators.required),
  state: new FormControl('',Validators.required),
  id: new FormControl('',Validators.required) 
});
  ngOnInit(): void {
     this.getEmployee();
  }
getEmployee(){

  if(this.id) this.employeeService.GetEmployeeById(this.id).subscribe({
    next : emp => this.employee = emp,
    error : error=>alert(error)
  });
}
onSubmit(){
   this.employeeService.UpdateEmployee(this.EmpForm.value).subscribe({
    next:()=>this.route.navigateByUrl('/'),
    error:()=>alert("Please check...!")
   })
}
}

update.component.html

<p>update works!</p>
<div class="d-flex justify-content-center mt-10">
    <div class="col-10">
        
        <div >
            <form  *ngIf="employee" [formGroup]="EmpForm" (ngSubmit)="onSubmit()">
            <fieldset>
              

              <div class="mb-3">
                <label for="disabledTextInput" class="form-label">First Name</label>
                <input type="text" id="firstName"  formControlName="firstName"  class="form-control" [(ngModel)]="employee.firstName" >
              </div>
              
              <div class="mb-3">
                <label for="disabledTextInput" class="form-label">Last Name</label>
                <input type="text" id="lastName"  formControlName="lastName"  class="form-control"  [(ngModel)]="employee.lastName">
              </div>

              <div class="mb-3">
                <label for="disabledTextInput" class="form-label">Street</label>
                <input type="text" id="street"  formControlName="street"  class="form-control"  [(ngModel)]="employee.street">
              </div>

              <div class="mb-3">
                <label for="disabledTextInput" class="form-label">City</label>
                <input type="text" id="city" formControlName="city" class="form-control"  [(ngModel)]="employee.city">
              </div>

              <div class="mb-3">
                <label for="disabledTextInput" class="form-label">State</label>
                <input type="text" id="state" formControlName="state"  class="form-control"  [(ngModel)]="employee.state">
              </div>
              
              <input type="hidden" id="id"  formControlName="id"  class="form-control" [(ngModel)]="employee.id" >
             <div class="d-grid">
                <button class="btn btn-lg btn-primary mt-3" type="submit">
                     Submit
                </button>
              </div>   
            </fieldset>
        </form> 
    </div> 

Update Delete Component

delete.component.ts

import { Component, OnInit } from '@angular/core';
import { EmployeeService } from '../employee.service';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
  selector: 'app-delete',
  templateUrl: './delete.component.html',
  styleUrls: ['./delete.component.scss']
})
export class DeleteComponent implements OnInit {
employee?:any;
id?:any; 

constructor(private employeeService:EmployeeService, private router : ActivatedRoute, private route:Router)
{ 
    this.id =this.router.snapshot.paramMap.get('id');
} 
  ngOnInit(): void {    
    this.getEmployee();
  }
  getEmployee(){
   
    if(this.id) this.employeeService.GetEmployeeById(this.id).subscribe({
      next : emp => this.employee = emp,
      error : error=>alert(error)
    });
  }
  onSubmit(){   
      this.employeeService.RemoveEmployee(this.id).subscribe({
      next : ()=>this.route.navigateByUrl('/'),
      error :()=>alert("Please check..!")
     
    });
  } 
}

delete.component.html

<div class="d-flex justify-content-center mt-10">
    <div class="col-10">
        
        <div *ngIf="employee"><form>
            <fieldset disabled>
              
              <div class="mb-3">
                <label for="disabledTextInput" class="form-label">First Name</label>
                <input type="text" id="" class="form-control" placeholder="{{ employee.firstName }}">
              </div>
              
              <div class="mb-3">
                <label for="disabledTextInput" class="form-label">Last Name</label>
                <input type="text" id="" class="form-control" placeholder="{{ employee.lastName }}">
              </div>

              <div class="mb-3">
                <label for="disabledTextInput" class="form-label">Street</label>
                <input type="text" id="" class="form-control" placeholder="{{ employee.street }}">
              </div>

              <div class="mb-3">
                <label for="disabledTextInput" class="form-label">City</label>
                <input type="text" id="" class="form-control" placeholder="{{ employee.city }}">
              </div>

              <div class="mb-3">
                <label for="disabledTextInput" class="form-label">State</label>
                <input type="text" id="" class="form-control" placeholder="{{ employee.state }}">
              </div>  
            </fieldset>
        </form>
            <div class="d-grid">
                <button class="btn btn-lg btn-primary mt-3" type="submit" (click)="onSubmit()">
                     Submit
                </button>
              </div> 
    </div> 

Root App Updating

Update app-routing. module

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  {path:'',loadChildren:()=>import('./Employee/employee.module').then(emp=>emp.EmployeeModule)},
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Update app.component.html

  
  <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'>
 
<div class="d-flex justify-content-center mt-5">
   
    <div class="col-0">
        <h5 class="mb-0">
            <a routerLink="/Create/" class="text-dark text-decoration-none">
                <button class="btn btn-primary">Add Employee</button> 
            </a>
        </h5>
       
    <br>
<router-outlet></router-outlet>
    </div>
</div>

Related Article – How to Create a Complete Login Page using Angular and .NET Core

Get List

Update record

Delete Record

The post How to Create CRUD operation using Angular and ASP.NET Core Web API appeared first on Tech Insights.

]]>
https://reactconf.org/how-to-create-crud-operation-using-angular-and-asp-net-core-web-api/feed/ 0 1481
How to Create a Complete Login Page using Angular and .NET Core https://reactconf.org/complete-login-page-using-angular-16-and-net-core-7/ https://reactconf.org/complete-login-page-using-angular-16-and-net-core-7/#respond Wed, 23 Aug 2023 06:49:30 +0000 https://labpys.com/?p=1448 In this tutorial, we’ll discuss the process of building a comprehensive login page using Angular 16 and .NET Core 7. Our approach will involve following a step-by-step methodology within the …

The post How to Create a Complete Login Page using Angular and .NET Core appeared first on Tech Insights.

]]>
In this tutorial, we’ll discuss the process of building a comprehensive login page using Angular 16 and .NET Core 7. Our approach will involve following a step-by-step methodology within the context of clean architecture.

Pre-requisite

Creating WebAPI using ASP.Net Core

Dotnet new  – Create  a new project based on the specified template

.NET CLI

dotnet new webapi -n Login_Out_DotNet_Angular

Install the Packages

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.EntityFrameworkCore.Sqlite
  • Microsoft.AspNetCore.Identity

Project folder structure

Create Core Folder

Create a model in the Entities folder inside Core Folder

Path:/Core/Entities/Users.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;

namespace Login_Out_DotNet_Angular.Core.Entities
{
    public class Users : IdentityUser
    {
        public string DisplayName { get; set; }
        public Address Address { get; set; }
    }
}

Path:/Core/Entities/Address.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace Login_Out_DotNet_Angular.Core.Entities
{
    public class Address
    {
        
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        [Required]
        public string UserId { get; set; }
        public Users User { get; set; }
    }
}

Create Infrastructure Folder

Create a DbContext class that communicates to the database.

Path:/ Infrastructure/Data/AppIdentityDbContext.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Login_Out_DotNet_Angular.Core.Entities;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace Login_Out_DotNet_Angular.Infrastructure.Data
{
    public class AppIdentityDbContext : IdentityDbContext<Users>
    {
        public AppIdentityDbContext(DbContextOptions<AppIdentityDbContext> options) : base(options)
        {

        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }

Configure AppSettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "Connection" :"Data Source = Identity.db"
  },
  "AllowedHosts": "*"
}

 Create the Extension folder

Path:/ Extensions/ApplicationServiceExtension.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Login_Out_DotNet_Angular.Core.Entities;
using Login_Out_DotNet_Angular.Infrastructure.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

namespace Login_Out_DotNet_Angular.Extensions
{
    public static class ApplicationServiceExtension
    {
        public static IServiceCollection AddIdentityService(this IServiceCollection services, IConfiguration config)
        {

            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen();
            services.AddDbContext<AppIdentityDbContext>(option =>
            {
                option.UseSqlite(config.GetConnectionString("Connection"));
            });

            services.AddIdentity<Users, IdentityRole>(opt =>
           {
               // add identity option                 
               opt.Password.RequiredLength = 8;
               opt.Password.RequireNonAlphanumeric = false;
               opt.Password.RequireDigit = false;
               opt.Password.RequireUppercase = false;

           })
           .AddEntityFrameworkStores<AppIdentityDbContext>()
           .AddUserManager<UserManager<Users>>()
           .AddSignInManager<SignInManager<Users>>()
           .AddDefaultTokenProviders();


            services.AddCors(Opt =>
            {

                 Opt.AddDefaultPolicy(opt=> 
                 {
                    opt.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin();
                 });

                // Opt.AddDefaultPolicy("CorsPolicy", policy =>
                //  {
                //      policy.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:4200/");
                //  });
            });

            return services;
        }
    }
}

Configure the Program.cs class

Path:/ Program.cs

using Login_Out_DotNet_Angular.Core.Entities;
using Login_Out_DotNet_Angular.Extensions;
using Login_Out_DotNet_Angular.Infrastructure.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle

builder.Services.AddIdentityService(builder.Configuration);

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.UseCors(); 

app.Run();

Now run Migrations

dotnet ef migrations add initialcreate  -o Migrations 

dotnet ef database update

Create folder DTO

Create folder DTO and inside the folder create classes LoginDto, UserDto, RegisterDto.

path: / DTO/LoginDto.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Login_Out_DotNet_Angular.DTO
{
    public class LoginDto
    {
        public string Email { get; set; }
        public string Password { get; set; }
    }
}

Path:/ DTO/UserDto.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Login_Out_DotNet_Angular.DTO
{
    public class UserDto
    {
        public string Email { get; set; }
        public string DisplayName { get; set; } 
    }
}

path:/ DTO/ RegisterDto.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Login_Out_DotNet_Angular.DTO
{
    public class RegisterDto
    {
        public string Email { get; set; }
        public string Password { get; set; }
        public string DisplayName { get; set; } 
    }
}

Create Controller

The Now create Account Controller in the Controller folder.

Path:/Controllers/AccountController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Login_Out_DotNet_Angular.Core.Entities;
using Login_Out_DotNet_Angular.DTO;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace Login_Out_DotNet_Angular.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AccountController : ControllerBase
    {
        private readonly UserManager<Users> _userManager;
        private readonly SignInManager<Users> _signInManager;

        public AccountController(UserManager<Users> userManager, SignInManager<Users> signInManager)
        {
            _userManager = userManager;
            _signInManager = signInManager;
        }

        [HttpPost("login")]
        public async Task<ActionResult<UserDto>> Login(LoginDto loginDto)
        {
            var user = await _userManager.FindByEmailAsync(loginDto.Email);
            if (user == null) return Ok("User Doest Not Exist");
            var result = await _signInManager.CheckPasswordSignInAsync(user, loginDto.Password, false);
            if (!result.Succeeded) return BadRequest("Please check Credential try again...!");

            return new UserDto
            {
                Email = user.Email,
                DisplayName = user.DisplayName
            };

        }
        [HttpPost("register")]
        public async Task<ActionResult<UserDto>> register(RegisterDto registerDto)
        {
            var user = new Users
            {
                DisplayName = registerDto.DisplayName,
                Email = registerDto.Email,
                UserName = registerDto.Email
                 
            };

            var result = await _userManager.CreateAsync(user, registerDto.Password);

            if (!result.Succeeded) return BadRequest("Please check...!");

            return new UserDto
            {
                DisplayName = registerDto.DisplayName,
                Email = registerDto.Email
            };
        }
    }
}
Now Test API using Postman

Creating a User Interface using Angular 16

Now Create Client Side User Interface using Angular 16

To create an Angular project first we need to install Node.js and angular

Download the Node.js installer here

Install angular 16

npm install -g @angular/cli

Create a Project

Ng new client

cd client
ng serve

install the bootstrap

ng add ngx-bootstrap

then add then bootstrap in angular.json file

  "styles": [
              "./node_modules/ngx-bootstrap/datepicker/bs-datepicker.css",
              "./node_modules/bootstrap/dist/css/bootstrap.min.css",
              "src/styles.css"
            ],

Create components using CLI command

ng g c home/home --flat --skip-tests
ng g c account/login/login  --flat --skip-tests
Creating Ng  routing module
ng g m account/account-routing  --flat
create Ng module
ng g m account/account  --flat
Create Ng service
ng g s account/account  --flat --skip-tests

Now in the app-routing.module  update routes

path:/ app/ app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';

const routes: Routes = [
  
  {path:'', loadChildren: ()=>import('./account/account.module').then(l=>l.AccountModule)},
  {path:'home', component:HomeComponent},
  {path:'**',redirectTo:'',pathMatch:'full'}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

In Ng Module import the modules

path:/ app/ app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { HomeComponent } from './home/home.component';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
      ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

and in the app-component.html file update router-outlet tag

path:/ app/app-component.html

<router-outlet></router-outlet>

Create a Shared folder

Inside the shared folder create another folder module in that folder create the interface

Path:/ app/shared/module/Users.ts

export interface Users{
    displayName : string,
    Email : string
}

Now in the account routing module update the routing

Path:/ app/account/ account-routing.module.ts

import { Component, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './login/login.component';

const routes : Routes=[
  {path:'', component:LoginComponent}
]

@NgModule({
  declarations: [],
  imports: [
    
    RouterModule.forChild(routes)
  
  ],
  exports:[
    RouterModule
  ]
})

in Ng module import the modules AccountRoutingModule, ReactiveFormsModule

path:/ app/account/ account.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; 
import { AccountRoutingModule } from './account-routing.module';
import { LoginComponent } from './login/login.component';
import { ReactiveFormsModule } from '@angular/forms';
 

@NgModule({
  declarations: [
    LoginComponent
  ],
  imports: [
    CommonModule,  
    AccountRoutingModule,
    ReactiveFormsModule
     
  ]
})
export class AccountModule { }

Create services for server communication.

path:/ app/account/ account.service.ts

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Users } from '../shared/module/users';
import { map } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class accountService {
  baseUrl = "https://localhost:7228/api/";
  constructor(private http : HttpClient, private route : Router) { }

  login(values:any){
    return this.http.post<Users>(this.baseUrl + 'account/login', values).pipe(
        map(users => { 
          localStorage.setItem('username',users.displayName);    
      })
    )
  }

  logout(){
    localStorage.removeItem('username');    
    this.route.navigateByUrl('/');
  }
}

Now open the login component then update

Path:/ app/account/login/ login.component.ts

import { Component } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { accountService } from '../account.service';
 

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent {

  title : string ='Login From';

  loginForm = new FormGroup({
    email : new FormControl('',Validators.required),
    password: new FormControl('',Validators.required)
  })
   constructor(private accountService: accountService, private router: Router){}

  onSubmit(){
    this.accountService.login(this.loginForm.value).subscribe({
      next:()=> this.router.navigateByUrl('/home'),
      error:()=> alert("Please check Credential...!") 
    })    
  }
}

Next, open the login.component.html and update

Path:/ app/account/login/ login.component.html

<div class="d-flex justify-content-center mt-5">
    <div class="col-3">
        <form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
            <div class="text-center mb-4">
                <h1 class="mb-3">
                    Login    
                </h1>
            </div>
            <div class="form-floating mb-3">
                <input type="email" formControlName="email"  class="form-control" id="floatingInput" placeholder="Email">
                <label for="floatingInput">Email address</label>
              </div>
              <div class="form-floating">
                <input type="password" formControlName="password" class="form-control" id="floatingPassword" placeholder="Password">
                <label for="floatingPassword">Password</label>
              </div>
              <div class="d-grid">
                <button class="btn btn-lg btn-primary mt-3" type="submit">
                    Sign in
                </button>
              </div>
        </form>
    </div>
</div>

Then Run Application

More Articles – How to Implement JWT Authentication in Asp.Net Core Web API

The post How to Create a Complete Login Page using Angular and .NET Core appeared first on Tech Insights.

]]>
https://reactconf.org/complete-login-page-using-angular-16-and-net-core-7/feed/ 0 1448