--Blazor maitains persistant HTTP connection between the client(Browser) and the server using SignalR.
--On Button click the event sent to the server over SignalR connection. The server will hanlde the event & send back an updated HTML to the client.
--The Html sent maynot be the entire Html Page but a small part of it & hence the performance is faster.
--3 Hosting Models
---Blazor server
---Blazor assembly web App
---Blazor hybrid
--Create Blazor WebAssembly App
---Check checkbox ASP.Net Core Hosted
--In .Server Project
---Install from Nuget Package --EntityFramework
--In .Shared Project
---Add Models folder and class file
--We will start writing code snippet from .Server Project.
I. Models>>DatabaseContext.cs and below are code snippets
using Microsoft.EntityFrameworkCore;
using UserInfo.Shared.Models;
namespace UserInfo.Server.Models
{
public partial class DatabaseContext:DbContext
{
public DatabaseContext() { }
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }
public virtual DbSet<UsersInfo> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UsersInfo>(e =>
{
e.ToTable("UsersInfo");
e.Property(e => e.UserId).HasColumnName("UserId");
e.Property(e => e.UserName).HasMaxLength(50).IsUnicode(false);
e.Property(e => e.Address).HasMaxLength(int.MaxValue).IsUnicode(false);
e.Property(e => e.MobileNo);
e.Property(e => e.EmailId).HasMaxLength(int.MaxValue).IsUnicode(false);
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
II. Interfaces>>IUserInfo.cs and below are code snippets
using UserInfo.Shared.Models;
namespace UserInfo.Server.Interfaces
{
public interface IUserInfo
{
public List<UsersInfo> GetAllUsers();
public UsersInfo GetUserInfo(int userId);
public bool AddUser(UsersInfo usersInfo);
public bool RemoveUser(int userId);
public bool UpdateUser(UsersInfo usersInfo);
}
}
III. Services>>UserInfoImpl.cs and below are code snippets
using UserInfo.Shared.Models;
using UserInfo.Server.Models;
using UserInfo.Server.Interfaces;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Server.IIS.Core;
namespace UserInfo.Server.Services
{
public class UserInfoImpl:IUserInfo
{
readonly DatabaseContext context = new();
public UserInfoImpl(DatabaseContext context) {
this.context = context;
}
public bool AddUser(UsersInfo usersInfo)
{
try
{
context.Users.Add(usersInfo);
var res = context.SaveChanges();
if (res > 0)
return true;
}
catch { throw; }
return false;
}
public bool UpdateUser(UsersInfo usersInfo)
{
try
{
context.Entry(usersInfo).State=EntityState.Modified;
var res = context.SaveChanges();
if (res > 0)
return true;
}
catch { throw; }
return false;
}
public List<UsersInfo> GetAllUsers()
{
try
{
return context.Users.ToList();
}
catch { throw; }
}
public UsersInfo GetUserInfo(int userId)
{
try
{
UsersInfo? userInfo = context.Users.Find(userId);
if (userInfo != null)
{
return userInfo;
}
else
throw new ArgumentNullException();
}
catch { throw; }
}
public bool RemoveUser(int userId)
{
try
{
UsersInfo? userInfo = context.Users.Find(userId);
if (userInfo != null)
{
context.Users.Remove(userInfo);
var res = context.SaveChanges();
if (res > 0)
return true;
}
}
catch { throw; }
return false;
}
}
}
IV. Controllers>>UserController.cs and below are code snippets
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using UserInfo.Server.Interfaces;
using UserInfo.Shared.Models;
namespace UserInfo.Server.Controllers
{
[Route("api/User")]
[ApiController]
public class UserController : ControllerBase
{
private readonly IUserInfo user;
public UserController(IUserInfo user)
{
this.user = user;
}
[HttpGet]
public async Task<List<UsersInfo>> Get()
{
return await Task.FromResult(user.GetAllUsers());
}
[HttpGet("{id}")]
public IActionResult Get(int id)
{
var res =user.GetUserInfo(id);
if(res != null)
{
return Ok(res);
}
else
{
return NotFound();
}
}
[HttpPost]
public bool Post(UsersInfo userInfo)
{
var res = user.AddUser(userInfo);
if (res)
return true;
return false;
}
[HttpPut]
public bool Put(UsersInfo userInfo)
{
var res = user.UpdateUser(userInfo);
if (res)
return true;
return false;
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
var res = user.RemoveUser(id);
if (res)
return Ok(res);
return NotFound();
}
}
}
V. AppSettings.json and below are code snippets
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"MyConn": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=BlazorAppDB;Integrated Security=True;Encrypt=False;TrustServerCertificate=False;"
}
}
VI. Program.cs and below are code snippets
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.EntityFrameworkCore;
using UserInfo.Server.Interfaces;
using UserInfo.Server.Models;
using UserInfo.Server.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<DatabaseContext>(x => x.UseSqlServer(builder.Configuration.GetConnectionString("MyConn")));
// Add services to the container.
builder.Services.AddScoped<IUserInfo,UserInfoImpl>();
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
app.MapControllers();
app.MapFallbackToFile("index.html");
app.Run();
--Then we will start writing code snippet from .Shared Project.
I. Models>>UsersInfo.cs and below are code snippets
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
namespace UserInfo.Shared.Models
{
public class UsersInfo
{
[Key] public int UserId { get; set; }
[Required]public string UserName { get; set; }
[Required] public string Address { get; set; }
[Required] public long MobileNo { get; set; }
[Required] public string EmailId { get; set; }
}
}
--Then we will start writing code snippet from .Client Project.
I. Pages>>FetchUserDetails.razor and below are code snippets
@page "/fetchuserdetails"
@using UserInfo.Shared.Models;
@inject HttpClient Http;//it will get the HTTP Request/Response from the provided URI.
@*API's URI*@
<h1>User Data</h1>
<p>Blazor Application CRUD Operation</p>
<div class="row">
<div class="col-md-6">
<a href="/user/add" class="btn btn-primary" role="button">
<i class="fas fa-user-plus"></i>
Add User
</a>
</div>
<div class="input-group col">
<input type="text" class="form-control" placeholder="Search User By Name" @bind="SearchString" @bind:event="oninput" @onkeyup="FilterUser" />
@if (SearchString.Length > 0)
{
<div class="input-group-append">
<button class="btn btn-danger" @onclick="ResetSearch">Reset</button>
</div>
}
</div>
</div>
<br />
@if (userList == null)
{
<p><em>Loading......</em></p>
}
else
{
<table class="table table-striped align-middle table-bordered">
<thead class="table-success">
<tr>
<th>UserId</th>
<th>UserName</th>
<th>Address</th>
<th>Mobile No</th>
<th>EmailId</th>
</tr>
</thead>
<tbody>
@foreach (var u in userList)
{
<tr>
<td>@u.UserId</td>
<td>@u.UserName</td>
<td>@u.Address</td>
<td>@u.MobileNo</td>
<td>@u.EmailId</td>
<td>
<a href="/user/edit/@u.UserId" class="btn btn-success" role="button">Edit</a>
<a href="/user/delete/@u.UserId" class="btn btn-danger" role="button">Delete</a>
</td>
</tr>
}
</tbody>
</table>
}
@code {
protected List<UsersInfo> userList = new();
protected List<UsersInfo> searchUserData = new();
UsersInfo user = new();
protected string SearchString { get; set; } = String.Empty;
protected override async Task OnInitializedAsync()
{
await GetUser();
}
protected async Task GetUser()
{
userList = await Http.GetFromJsonAsync<List<UsersInfo>>("api/User");
searchUserData = userList;
}
protected void FilterUser()
{
if (!string.IsNullOrEmpty(SearchString))
{
userList = searchUserData.Where(x => x.UserName.IndexOf(SearchString,
StringComparison.OrdinalIgnoreCase) != -1).ToList();
}
else
{
userList = searchUserData;
}
}
protected void DeleteConfirm(int UserID)
{
user = userList.FirstOrDefault(x => x.UserId == UserID);
}
public void ResetSearch()
{
SearchString = String.Empty;
userList = searchUserData;
}
}
II. Pages>>AddUser.razor and below are code snippets
@page "/user/add"
@page "/user/edit/{userId:int}"
@using UserInfo.Shared.Models;
@inject HttpClient Http;
@inject NavigationManager nav;
@*Navigation in Angular*@
<h1>@Title New User</h1>
<hr/>
<h4 class="bg-success text-center text-white">@Result</h4>
<EditForm Model="@user" OnValidSubmit="SaveUser">
<DataAnnotationsValidator/>
<div class="mb-3">
<label>Enter Name</label>
<InputText class="form-control" @bind-Value="user.UserName" />
<span><ValidationMessage For="@(()=>user.UserName)" /></span>
</div>
<div class="mb-3">
<label>Enter Address</label>
<InputTextArea class="form-control" @bind-Value="user.Address" />
<span><ValidationMessage For="@(()=>user.Address)" /></span>
</div>
<div class="mb-3">
<label>Enter Mobile No</label>
<InputNumber class="form-control" @bind-Value="user.MobileNo" />
<span><ValidationMessage For="@(()=>user.MobileNo)" /></span>
</div>
<div class="mb-3">
<label>Enter EmailId</label>
<InputText class="form-control" @bind-Value="user.EmailId" />
<span><ValidationMessage For="@(()=>user.EmailId)" /></span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">@BtnTxt</button>
<button type="reset" class="btn btn-light" @onclick="Cancel">Cancel</button>
</div>
</EditForm>
@code{
[Parameter]
public int userId{ get; set; }
protected string Title = "Add";
protected string BtnTxt = "Save";
protected UsersInfo user = new();
public string Result { get; set; } = string.Empty;
protected override async Task OnParametersSetAsync()
{
if(userId!=0)
{
Title = "Edit";
BtnTxt = "Update";
user = await Http.GetFromJsonAsync<UsersInfo>("api/User/" + userId);
}
}
protected async Task SaveUser()
{
if(user.UserId!=0)
{
await Http.PutAsJsonAsync("/api/User", user);
Result = "User data updated successfully.";
}
else
{
await Http.PostAsJsonAsync("/api/User", user);
Result = "New user added successfully.";
}
}
protected void Cancel()
{
nav.NavigateTo("/fetchuserdetails");
}
}
III. Pages>>DeleteUser.razor and below are code snippets
@page "/user/delete/{userId:int}"
@using UserInfo.Shared.Models;
@inject HttpClient Http;
@inject NavigationManager nav;
<h2>Delete User</h2>
<br/>
<div class="form-group">
<h4 class="bg-danger text-white">Do you want to delete user?</h4>
<table class="table">
<tbody>
<tr>
<td>Name</td>
<td>@user.UserName</td>
</tr>
<tr>
<td>Address</td>
<td>@user.Address</td>
</tr>
<tr>
<td>MobileNo</td>
<td>@user.MobileNo</td>
</tr>
<tr>
<td>EmailId</td>
<td>@user.EmailId</td>
</tr>
</tbody>
</table>
<div class="form-group">
<input type="submit" value="Delete" class="btn btn-danger" @onclick="(async()=>await RemoveUser(user.UserId))"/>
<input type="button" value="Cancel" class="btn btn-light" @onclick="(()=>Cancel())">Cancel</input>
</div>
</div>
@code{
[Parameter]
public int userId{ get; set; }
UsersInfo user = new();
protected override async Task OnInitializedAsync()
{
user = await Http.GetFromJsonAsync<UsersInfo>("api/User/" + userId);
}
protected void Cancel()
{
nav.NavigateTo("/fetchuserdetails");
}
protected async Task RemoveUser(int userId)
{
await Http.DeleteAsync("api/User/" + userId);
nav.NavigateTo("/fetchuserdetails");
}
}
IV. Shared>>NavMenu.razor and below are code snippets
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">UserInfo</a>
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</div>
<div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="fetchuserdetails">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch User Details
</NavLink>
</div>
</nav>
</div>
@code {
private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
}
V. App.razor and below are code snippets
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
VI. Program.cs and below are code snippets
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using UserInfo.Client;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
--Table created in DB
No comments:
Post a Comment