ASP .NET Core MVC - Criando um Portfólio digital - II


Hoje vamos continuar a criação de um portfólio digital usando a ASP .NET Core MVC no ambiente do NET 6.

Vamos continuar a criação do nosso portfólio digital definindo as Partial Views e criando os demais recursos no projeto.


Antes de continuar a criação dos demais recursos vamos explicar o código do controlador PortfolioController:
 

using Microsoft.AspNetCore.Mvc;
using PortfolioMvc.Services;
using PortfolioMvc.ViewModels;

namespace PortfolioMvc.Controllers
{
    public class PortfolioController : Controller
    {
        private readonly IProjetosService _projetoService;
        private readonly IEmailService _emailService;

        public PortfolioController(IProjetosService projetoService,
            IEmailService emailService)
        {
            _projetoService = projetoService;
            _emailService = emailService;
        }

        public IActionResult Index()
        {
            var projetos = _projetoService.GetProjetos().Take(3).ToList();

            var modelo = new PortfolioViewModel()
            {
                Projetos = projetos
            };
            return View(modelo);
        }

        public IActionResult Projetos()
        {
            var projetos = _projetoService.GetProjetos();
            return View(projetos);
        }

        [HttpGet]
        public IActionResult Contato()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Contato(ContatoViewModel contatoViewModel)
        {
            await _emailService.Enviar(contatoViewModel);
            return RedirectToAction("Obrigado");
        }

        public IActionResult Obrigado()
        {
            return View();
        }
    }
}


1- Injetamos no construtor do controlador os serviços criados;


2-  Criamos o método Action Index que vai o portfólio com uma amostra de 3 projetos. Para isso obtemos 3 projetos e atribuímos à propriedade Projetos definida na view model PortfolioViewModel;

 

3- Criamos o método Action Projetos que vai exibir os principais projetos;

 

4- No método Action Contato vamos definir no GET a apresentação do formulário de contato e no POST o seu processamento com o envio do email usando o SendGrid e redirecionamento para a Action Obrigado.;

Criando as views e partial views do projeto

Vamos criar a view Index.cshtml que vai exibir o portfólio principal:

@model PortfolioViewModel

@{
    ViewData["Title"] = "Página principal";
}

<partial name="_Apresentacao"/>

<partial name="_Experiencia"/>

<partial name="_ProjetosAmostra" model="Model?.Projetos"/>

<partial name="_Rodape"/>

No código da view usamos a view model PortfolioViewModel e definimos 4 partial views para facilitar e segmentar a exibição de cada seção do portfólio facilitando assim a manutenção do código.

Uma Partial View é um arquivo de marcação Razor(. cshtml) que renderiza a saída HTML dentro da saída processada de outro arquivo de marcação.  Elas não podem ser usadas para manter os elementos de layout comuns.

As partial views são usadas para :

  1. Dividir arquivos de marcação grandes em componentes menores;
  2. Reduzir a duplicação de conteúdo de marcação comum em arquivos de marcação;

ssim teremos que criar as seguintes partial views na pasta Shared:

  1. _Apresentacao
  2. _Experiencia
  3. _ProjetosAmostra
  4. _Rodape

Estas partial views usam imagens que foram incluídas na pasta wwwroot/imagens do projeto.

A seguir temos o código de cada partial view:

1 - _Apresentacao.cshtml

<div class="text-center">
    <h4 class="display-3">Olá, sou o Macoratti</h4>

    <h5>Sou desenvolvedor especializado em tecnologías .NET.</h5>

    <img id="foto"
         src="~/imagens/macoratti.jpg" alt="Foto do Macoratti" />

</div>
<div class="text-center">
    <img id="imagem-dotnet" src="~/imagens/dotnet1.jpg" alt="logo dotnet" />
</div>

<div class="row justify-content-center text-center" style="background-color : #f7f7f7">
    <div class="col col-md-7 secao-bemvindo">
        <h3>Bem-vindo ao meu portfólio</h3>
        <p>
          Estou atuando no mercado há mais de 20 anos onde trabalhei com diversas equipes e
          em diversos cenários usando as mais variadas tecnologias e oferecendo soluções para desktop, web e mobile.        
        </p>
    </div>
</div>

2 - _Experiência.cshtml

<div style="margin-top: -105px">

    <div class="row justify-content-md-center text-center">
        <div class="col col-3 bg-white experiencia" style="border-radius: 15px 0 0 15px; box-shadow: 0 5px 5px 0 gray">
           <i class="bi-hdd-fill"></i>
            <h3>Back-end</h3>

            <p>
                Desenvolvimento de aplicações back-end robustas desde o projeto, testes unitários e deploy em produção
            </p>

            <p class="text-primary cabecalho">
                Stack:
            </p>

            <p>
                ASP.NET Core, SQL Server
            </p>

            <p class="text-primary cabecalho">
                Experiência:
            </p>

            <ul>
                <li>Web APIs</li>
                <li>ASP.NET Core MVC</li>
                <li>Entity Framework Core</li>
                <li>Blazor</li>
                <li>Dapper</li>
                <li>Principios SOLID</li>
            </ul>

        </div>
        <div class="col col-3 bg-white experiencia" style="border-radius: 0 15px 15px 0; box-shadow: 0 5px 5px 0 gray">
            <i class="bi-code-slash"></i>
            <h3>Front-End</h3>
            <p>
                Criação de aplicações front-ends usando as ferramentas mais atuais do mercado integradas ao back-end
            </p>

            <p class="text-primary cabecalho">
                Stack:
            </p>

            <p>
                React, Angular, Blazor
            </p>

            <p class="text-primary cabecalho">
                Experiência:
            </p>

            <ul>
                <li>React Hooks</li>
                <li>Angular Material</li>
                <li>Blazor WASM</li>
                <li>jQuery</li>
                <li>Javascript</li>
                <li>HTML/CSS</li>
            </ul>
        </div>
    </div>
</div>

3 - _ProjetoAmostra.cshtml

@model IEnumerable<Projeto>

@if (Model is not null)
{
    <div class="text-center" style="padding-top: 6rem;">
        <h1>Projetos mais recentes</h1>
        <p>Alguns dos projetos mais recentes onde trabalhei.</p>
    </div>

    <partial name="_Projetos" model="Model" />
}

4 - _Rodape.cshtml

<div id="footer" class="text-center">
    <div class="container-fluid">
        <div class="socials-media text-center">
            <ul class="list-unstyled">
                <li><a href="https://www.facebook.com/Macoratti.net/"><i class="bi bi-facebook"></i></a></li>
                <li><a href="https://twitter.com/macorati"><i class="bi bi-twitter"></i></a></li>
                <li><a href="https://www.instagram.com/macorattinet/"><i class="bi bi-instagram"></i></a></li>
                <li><a href="https://www.linkedin.com/in/jose-macoratti-2507156a/"><i class="bi bi-linkedin"></i></a></li>
            </ul>
        </div>
        <p>&copy; Copyright Macoratti.net</p>
    </div>
</div>
Além destas vamos usar também a partial view _Projetos.cshtml
@model IEnumerable<Projeto>

@if (Model is not null)
{
    <div class="container">
        <div class="row row-cols-1 row-cols-md-3 g-4">
            @foreach (var projeto in Model)
            {
                <div class="col">
                    <div class="card h-100">
                        <img src="@projeto.ImagemURL" class="card-img-top" alt="imagem projeto" />
                        <div class="card-body">
                            <h5 class="card-title">@projeto.Titulo</h5>
                            <p class="card-text">@projeto.Descricao</p>
                        </div>
                        <div class="card-footer">
                            <a class="btn btn-primary" href="@projeto.Link" target="_blank"
                            rel="noopener noreferrer">Visitar</a>
                        </div>
                    </div>
                </div>
            }
        </div>
    </div>
}

Esta partial view é usada também pela View Projetos.cshtml:

@model IEnumerable<Projeto>

@{
    ViewData["Title"] = "Projetos";
}

<div class="container">
    <h1>Meus projetos</h1>
    <p>Principais projetos onde trabalhei</p>
</div>

<partial name="_Projetos" model="Model" />

 

A seguir temos a view Contato.cshtml que vai apresentar o formulário de contato :

@{
    ViewData["Title"] = "Contato";
}

<img src="~/imagens/contato.jpg" width="100" height="100"/>

<h1>Formulario de Contato</h1>

<form asp-controller="Portfolio" asp-action="Contato">
    <div class="mb-3">
        <label for="nome" class="form-label">Nome</label>
        <input type="text" class="form-control" id="nome" name="nome" placeholder="Informe o nome" />
    </div>
    <div class="mb-3">
        <label for="email" class="form-label">Email</label>
        <input type="email" class="form-control" id="email" name="email" placeholder="nome@email.com" />
    </div>
    <div class="mb-3">
        <label for="mensagem" class="form-label">Mensagem</label>
        <textarea class="form-control" id="mensaje" name="mensagem" rows="4"></textarea>
    </div>
    <button type="submit" class="btn btn-primary">Enviar</button>
</form>

Neste código estou usando HTML 5 e validando de forma bem simples os campos do formulário.

Para concluir temos a view Obrigado.cshtml :

<div class="jumbotron jumbotron-fluid">
  <div class="container">

    <h3 class="display-4">Grato pelo seu contato</h3>
      <p>Vou responder sua mensagem o mais brever possível.</p> 
      <hr class="my-4">
      <p class="lead">
       <div><a asp-action="Index" asp-controller="Home">Retornar</a></div>
     </p>
  </div>
</div>

E com isso concluímos a criação deste projeto simples mas funcional que você pode usar como ponto de partida para criar um portfólio mais robusto.

Pegue o projeto aqui : PortfolioMvc.zip

"Deus "retribuirá a cada um conforme o seu procedimento".
Ele dará vida eterna aos que, persistindo em fazer o bem, buscam glória, honra e imortalidade."
Romanos 2:6,7

Referências:


José Carlos Macoratti