Blazor - CRUD com ADO.NET em camadas - III
Hoje vamos iniciar a criação de um projeto em camadas que realizar o CRUD usando como cliente uma aplicação Blazor Server App. |
Continuando a segunda parte do artigo vamos agora definir o projeto Blazor Server.
Definindo o projeto Blazor : Configuração e ajustes
O projeto BlzCrud.App representa a camada de apresentação onde vamos definir os componentes Blazor que vão interagir com o cliente e usar os recursos das demais camadas.
Vamos iniciar definindo no arquivo appsettings.json a string de conexão com o banco de dados :
{ "ConnectionStrings": { "DefaultConnection": "Data Source=.;Initial Catalog=CadastroDB;IntegratedSecurity=True" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" } |
A seguir vamos registrar os serviços na classe Program:
using BlzCrud.Application.Services;
using BlzCrud.Domain.Interfaces;
using BlzCrud.Infra.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddScoped<IClienteService, ClienteService>();
builder.Services.AddSingleton<IDataService, DataService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
|
Agora vamos incluir no arquivo _Imports.razor os usings que iremos usar no projeto Blazor:
@using
System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using BlzCrud.App @using BlzCrud.App.Shared @using BlzCrud.Application.Services @using BlzCrud.Domain.Interfaces @using BlzCrud.Domain.Entities |
Na pasta wwwroot do projeto vamos criar a pasta images e incluir nesta pasta a imagem clientes.jpg que iremos usar na página Index.razor.
A seguir vamos ajustar o arquivo NavMenu.razor da pasta Shared com o código a seguir:
... < 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="clientes"> <span class="oi oi-plus" aria-hidden="true"></span> Clientes </NavLink> </div> </nav> </div> ,,, |
Vamos alterar o código do componente Index.razor da pasta Pages conforme abaixo:
@page
"/" < PageTitle>Index</PageTitle>< img src="/images/clientes.jpg" /> |
Criando os componentes Blazor
A seguir vamos criar na pasta Pages os componentes Blazor que vão permitir ao usuário realizar as operações CRUD.
1- Componente Clientes.razor : Exibe a relação dos clientes
@page "/clientes"
@inject IDataService clienteService
<NavLink class="nav-link" href="AddCliente">
<span class="oi oi-plus" aria-hidden="true"></span> Novo Cliente
</NavLink>
<h1>Cientes</h1>
@if (clientes == null)
{
<p><em>Carregando...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Email</th>
<th>Telefone</th>
<th>Ação</th>
</tr>
</thead>
<tbody>
@foreach (var cliente in clientes)
{
<tr>
<td>@cliente.ClienteId</td>
<td>@cliente.Nome</td>
<td>@cliente.Email</td>
<td>@cliente.Telefone</td>
<td>
<a class="nav-link" href="EditCliente/@cliente.ClienteId">
<span class="oi oi-pencil" aria-hidden="true"></span> Editar
</a>
<a class="nav-link" href="DeleteCliente/@cliente.ClienteId">
<span class="oi oi-trash" aria-hidden="true"></span> Deletar
</a>
</td>
</tr>
}
</tbody>
</table>
}
@code {
List<Cliente>? clientes;
protected override async Task OnInitializedAsync()
{
clientes = await Task.Run(() => clienteService.GetClientes());
}
}
|
2- Componente AddCliente.razor : Inclui um novo cliente
@page "/addCliente"
@inject IDataService clienteService
@inject NavigationManager NavigationManager
<h2>Criar Cliente</h2>
<hr />
<form>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label for="Nome" class="control-label">Nome</label>
<input for="Nome" class="form-control" @bind="@cliente.Nome" />
</div>
<div class="form-group">
<label for="Email" class="control-label">Email</label>
<input for="Email" class="form-control" @bind="@cliente.Email" />
</div>
<div class="form-group">
<label for="Nascimento" class="control-label">Nascimento</label>
<input for="Nascimento" class="form-control" @bind="@cliente.Nascimento" />
</div>
<div class="form-group">
<label for="Telefone" class="control-label">Telefone</label>
<input for="Telefone" class="form-control" @bind="@cliente.Telefone" />
</div>
<div class="form-group">
<label asp-for="Sexo" class="control-label"></label>
<select @bind="@cliente.Sexo" class="form-control">
<option value="">-- Selecione --</option>
<option value="Masculino">Masculino</option>
<option value="Feminino">Feminino</option>
</select>
</div>
<div class="form-group">
<label for="Renda" class="control-label">Renda</label>
<input for="Renda" class="form-control" @bind="@cliente.Renda" />
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-md-4">
<div class="form-group">
<input type="button" class="btn btn-primary" @onclick="@CreateCliente" value="Salvar" />
<input type="button" class="btn btn-warning" @onclick="@Cancela" value="Cancelar" />
</div>
</div>
</div>
</form>
@code {
Cliente cliente = new Cliente();
protected void CreateCliente()
{
clienteService.AddCliente(cliente);
NavigationManager.NavigateTo("Clientes");
}
void Cancela()
{
NavigationManager.NavigateTo("Clientes");
}
}
|
3- Componente EditCliente.razor : Edita os dados de um cliente
@page "/editCliente/{clienteId}"
@inject IDataService clienteService
@inject NavigationManager NavigationManager
<h2>Editar Cliente</h2>
<hr />
<form>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<input for="Name" class="form-control" @bind="@cliente.ClienteId" />
</div>
<div class="form-group">
<label for="Nome" class="control-label">Nome</label>
<input for="Nome" class="form-control" @bind="@cliente.Nome" />
</div>
<div class="form-group">
<label for="Email" class="control-label">Email</label>
<input for="Email" class="form-control" @bind="@cliente.Email" />
</div>
<div class="form-group">
<label for="Nascimento" class="control-label">Nascimento</label>
<input for="Nascimento" class="form-control" @bind="@cliente.Nascimento" />
</div>
<div class="form-group">
<label for="Telefone" class="control-label">Telefone</label>
<input for="Telefone" class="form-control" @bind="@cliente.Telefone" />
</div>
<div class="form-group">
<label asp-for="Sexo" class="control-label"></label>
<select @bind="@cliente.Sexo" class="form-control">
<option value="">-- Selecione --</option>
<option value="Masculino">Masculino</option>
<option value="Feminino">Feminino</option>
</select>
</div>
<div class="form-group">
<label for="Renda" class="control-label">Renda</label>
<input for="Renda" class="form-control" @bind="@cliente.Renda" />
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-md-4">
<div class="form-group">
<input type="button" @onclick="@UpdateCliente" class="btn btn-primary" value="Salvar" />
<input type="button" @onclick="@Cancelar" class="btn btn-warning" value="Cancelar" />
</div>
</div>
</div>
</form>
@code{
[Parameter]
public string clienteId { get; set; }
Cliente cliente = new Cliente();
protected override async Task OnInitializedAsync()
{
cliente = await Task.Run(()=> clienteService.GetCliente(Convert.ToInt32(clienteId)));
}
protected void UpdateCliente()
{
clienteService.UpdateCliente(cliente);
NavigationManager.NavigateTo("Clientes");
}
void Cancelar()
{
NavigationManager.NavigateTo("Clientes");
}
}
|
4- Componente DeleteCliente.razor : Deleta um cliente
@page "/deletecliente/{clienteId}"
@inject IDataService clienteService
@inject NavigationManager NavigationManager
<h3>Deseja deletar este cliente?</h3>
<hr />
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label>Id:</label>
<label>@cliente.ClienteId</label>
</div>
<div class="form-group">
<label>Nome:</label>
<label>@cliente.Nome</label>
</div>
<div class="form-group">
<label>Sexo:</label>
<label>@cliente.Sexo</label>
</div>
<div class="form-group">
<label>Email:</label>
<label>@cliente.Email</label>
</div>
<div class="form-group">
<label>Telefone:</label>
<label>@cliente.Telefone</label>
</div>
</div>
</div>
<hr />
<div class="row">
<div class="col-md-4">
<div class="form-group">
<input type="button" @onclick="@DeletarCliente" class="btn btn-danger" value="Deletar" />
<input type="button" @onclick="@Cancelar" class="btn btn-warning" value="Cancelar" />
</div>
</div>
</div>
@code {
[Parameter]
public string? clienteId { get; set; }
Cliente cliente = new Cliente();
protected override async Task OnInitializedAsync()
{
cliente = await Task.Run(()=> clienteService.GetCliente(Convert.ToInt32(clienteId)));
}
protected void DeletarCliente()
{
clienteService.DeleteCliente(Convert.ToInt32(clienteId));
NavigationManager.NavigateTo("Clientes");
}
void Cancelar()
{
NavigationManager.NavigateTo("Clientes");
}
}
|
Agora é só alegria...
Executando o projeto teremos o seguinte resultado:
Embora seja um projeto bem simples, você pode melhorá-lo em diversos aspectos como implementar o serviço assíncrono e remover a utilização dos Task.Run usada nos componentes Blazor pois isso não é recomendado. (Programação assíncrona com ADO.NET)
Assim fique a vontade e divirta-se...
Pegue o projeto aqui : BlzCrud_Adonet.zip (sem as referências)
"No último dia, o mais importante da festa, Jesus se
levantou e disse em alta voz: “Quem tem sede, venha a mim e beba!"
João 7:27
Referências:
NET - Unit of Work - Padrão Unidade de ...