A arquitetura Model-View-Controller (MVC) é um padrão de design testado no tempo que separa preocupações dentro de uma aplicação web, tornando mais fácil gerenciar a complexidade, componentes de teste em isolamento e características de escala ao longo do tempo. Na ASP.NET Core, MVC é um cidadão de primeira classe, fornecendo uma estrutura robusta para a construção de aplicações web modernas e mantendíveis. Este guia orienta você através de cada etapa de implementação de MVC em ASP.NET Core, desde a configuração inicial do projeto até as melhores práticas avançadas.

Compreender o padrão de MVC na Profundidade

Antes de mergulhar em código, é essencial entender como os três componentes centrais do MVC colaboram para lidar com uma solicitação do usuário. O padrão define responsabilidades claras:

  • Modelo: Representa a estrutura de dados e as regras de negócios. Não sabe sobre a interface ou como os dados são exibidos. Modelos são classes C# tipicamente simples que encapsulam propriedades, lógica de validação e acesso de dados (muitas vezes via Entity Framework Core).
  • Ver: Muda a interface do usuário. No ASP.NET Core, as visualizações são arquivos Razor (`.cshtml`) que combinam marcação HTML com código C# do lado do servidor. As visualizações devem somente exibir dados, não conter lógica complexa.
  • Controller: Atua como intermediário. Recebe solicitações HTTP, decide qual modelo usar e seleciona a visão apropriada para retornar. Os controladores contêm métodos de ação que mapeiam rotas específicas.

O fluxo de requisição típico no ASP.NET Core MVC: um usuário navega para uma URL (por exemplo, ], o middleware de roteamento direciona a requisição para a ação , a ação interage com o modelo (por exemplo, busca produtos de um banco de dados), empacota os dados em um modelo de visualização, e passa-o para a view. A view gera então uma resposta HTML enviada de volta para o cliente.

Pré-requisitos

  • [[FLT: 0]].NET SDK [[FLT: 1]] (versão 6.0 ou posterior). Download from [FLT: 2]] dotnet.microsoft.com[[[FLT: 3]].
  • Visual Studio, Visual Studio Code, ou qualquer editor de código preferido.
  • Familiaridade básica com conceitos de desenvolvimento de C# e web.

Passo 1: Criar um novo projeto MVC de núcleo ASP.NET

Você pode começar com o .NET CLI ou Visual Studio. Ambos fornecem um modelo de projeto que andaime a estrutura padrão de pasta MVC.

Usar a Linha de Comando

Abrir um terminal e executar:

dotnet new mvc -n MyMvcApp

Isto cria um projeto chamado em uma nova pasta. A estrutura gerada inclui , , , e (para arquivos estáticos).

Usando o Estúdio Visual

No Visual Studio, escolha Criar um novo projeto → selecionar ASP.NET Core Web App (Modelo-View-Controller)[ → configurar o nome e localização do projeto → escolher .NET versão (por exemplo, .NET 8). As mesmas pastas são criadas automaticamente.

Verificar as execuções do projecto:

cd MyMvcApp
dotnet run

Abra para ver a página inicial padrão.

Passo 2: Compreender a estrutura do projeto

O projeto com andaimes contém vários itens chave:

  • Controllers: Pasta vazia onde você adicionará classes de controle C#.
  • Modelos: Local para suas classes de domínio e modelos de visualização.
  • Visões : Tem uma pasta e por padrão, mais um layout .
  • Programa.cs: Inicialização de aplicativos, onde os serviços (incluindo MVC) estão configurados.

Abra e observe as linhas que habilitam MVC:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
var app = builder.Build();
...
app.MapControllerRoute(
 name: "default",
 pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();

Isto configura a rota padrão que mapeia URLs como para .

Passo 3: Criar uma Classe de Modelo

Os modelos representam os dados com os quais a aplicação trabalha. Comece criando um modelo dentro da pasta .

// Models/Product.cs
namespace MyMvcApp.Models;

public class Product
{
 public int Id { get; set; }
 public string Name { get; set; } = string.Empty;
 public decimal Price { get; set; }
 public string? Description { get; set; }
 public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
}

Você pode enriquecer modelos com anotações de dados para validação:

using System.ComponentModel.DataAnnotations;

public class Product
{
 public int Id { get; set; }

 [Required(ErrorMessage = "Product name is required.")]
 [StringLength(100)]
 public string Name { get; set; } = string.Empty;

 [Range(0.01, 10000)]
 public decimal Price { get; set; }

 [MaxLength(500)]
 public string? Description { get; set; }

 [Display(Name = "Created")]
 public DateTime CreatedAt { get; set; }
}

Em uma aplicação real, você normalmente adicionaria um contexto de banco de dados (Entity Framework Core) para modelos persistentes. Para este guia usaremos dados de memória para manter o foco no fluxo MVC.

Passo 4: Adicionando um Controlador

Controladores lidam com solicitações recebidas e orquestram a resposta. Crie uma dentro da pasta .

// Controllers/ProductsController.cs
using Microsoft.AspNetCore.Mvc;
using MyMvcApp.Models;
using System.Collections.Generic;

namespace MyMvcApp.Controllers;

public class ProductsController : Controller
{
 // Simulate a data source
 private static List<Product> _products = new List<Product>
 {
 new Product { Id = 1, Name = "Laptop", Price = 999.99m },
 new Product { Id = 2, Name = "Smartphone", Price = 599.99m },
 new Product { Id = 3, Name = "Tablet", Price = 399.99m }
 };

 // GET: /Products
 public IActionResult Index()
 {
 return View(_products); // Pass list to the view
 }

 // GET: /Products/Details/5
 public IActionResult Details(int id)
 {
 var product = _products.Find(p => p.Id == id);
 if (product == null)
 return NotFound();
 return View(product);
 }

 // GET: /Products/Create
 public IActionResult Create()
 {
 return View();
 }

 // POST: /Products/Create
 [HttpPost]
 [ValidateAntiForgeryToken]
 public IActionResult Create(Product product)
 {
 if (ModelState.IsValid)
 {
 product.Id = _products.Max(p => p.Id) + 1;
 product.CreatedAt = DateTime.UtcNow;
 _products.Add(product);
 return RedirectToAction(nameof(Index));
 }
 return View(product);
 }
}

Pontos-chave:

  • IactionResult é o tipo de retorno. Pode ser um , , , etc.
  • Nomes de ação mapeiam para ver em uma pasta com o nome do controlador ().
  • A ação tem duas sobrecargas: uma para GET (mostrar o formulário) e outra para POST (manejar a submissão do formulário).
  • protege contra falsificações de pedidos de acesso cruzado.

Passo 5: Criar vistas com sintaxe Razor

As vistas estão ao vivo em . O layout compartilhado está em .

Vista de Índice – Mostrar uma Lista

Criar [[FLT: 32]]:

@model IEnumerable<MyMvcApp.Models.Product>
@{
 ViewData["Title"] = "Product List";
}

<h2>@ViewData["Title"]</h2>

<table class="table table-striped">
 <thead>
 <tr>
 <th>@Html.DisplayNameFor(model => model.Id)</th>
 <th>@Html.DisplayNameFor(model => model.Name)</th>
 <th>@Html.DisplayNameFor(model => model.Price)</th>
 <th></th>
 </tr>
 </thead>
 <tbody>
 @foreach (var item in Model)
 {
 <tr>
 <td>@item.Id</td>
 <td>@item.Name</td>
 <td>@item.Price.ToString("C")</td>
 <td>
 <a asp-action="Details" asp-route-id="@item.Id">Details</a>
 </td>
 </tr>
 }
 </tbody>
</table>

<p>
 <a asp-action="Create" class="btn btn-primary">Create New Product</a>
</p>

Dicas de Razor: Use ] para mudar de HTML para C#, e /] helpers de tags para gerar URLs.

Vista de Detalhes

Criar :

@model MyMvcApp.Models.Product
@{
 ViewData["Title"] = "Product Details";
}

<h2>@Model.Name</h2>

<dl class="row">
 <dt class="col-sm-2">@Html.DisplayNameFor(model => model.Id)</dt>
 <dd class="col-sm-10">@Model.Id</dd>

 <dt class="col-sm-2">@Html.DisplayNameFor(model => model.Price)</dt>
 <dd class="col-sm-10">@Model.Price.ToString("C")</dd>

 <dt class="col-sm-2">@Html.DisplayNameFor(model => model.Description)</dt>
 <dd class="col-sm-10">@Model.Description</dd>

 <dt class="col-sm-2">@Html.DisplayNameFor(model => model.CreatedAt)</dt>
 <dd class="col-sm-10">@Model.CreatedAt</dd>
</dl>

<a asp-action="Index">Back to List</a>

Criar uma Vista com o Formulário

Criar :

@model MyMvcApp.Models.Product
@{
 ViewData["Title"] = "Create Product";
}

<h2>Create</h2>

<form asp-action="Create">
 <div asp-validation-summary="ModelOnly" class="text-danger"></div>

 <div class="form-group">
 <label asp-for="Name"></label>
 <input asp-for="Name" class="form-control" />
 <span asp-validation-for="Name" class="text-danger"></span>
 </div>

 <div class="form-group">
 <label asp-for="Price"></label>
 <input asp-for="Price" class="form-control" />
 <span asp-validation-for="Price" class="text-danger"></span>
 </div>

 <div class="form-group">
 <label asp-for="Description"></label>
 <textarea asp-for="Description" class="form-control"></textarea>
 </div>

 <button type="submit" class="btn btn-primary">Create</button>
 <a asp-action="Index" class="btn btn-secondary">Cancel</a>
</form>

@section Scripts {
 @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Assistentes de etiquetas de Razor como geram campos de formulário com a ligação e validação do modelo. O ] carrega scripts de validação do lado do cliente.

Passo 6: Adicionando Rotas e Rotas Personalizadas

MVC usa roteamento baseado em convenção por padrão. A rota em ] mapas . Você também pode adicionar roteamento de atributos para mais controle. Por exemplo, no controlador:

[Route("products")]
public class ProductsController : Controller
{
 [Route("")] // matches /products
 [Route("index")] // matches /products/index
 public IActionResult Index() { ... }

 [Route("{id:int}")] // matches /products/5
 public IActionResult Details(int id) { ... }
}

Esta abordagem é útil para APIs RESTful quando combinada com .

Passo 7: Usando ViewModels para dados complexos

Muitas vezes, você precisa passar mais de um objeto de dados para uma visualização, ou incluir propriedades extras (como listas selecionadas, títulos de página). É aí que os modelos de visualização entram. Crie uma classe de modelo de visualização em :

namespace MyMvcApp.Models.ViewModels;

public class ProductIndexViewModel
{
 public IEnumerable<Product> Products { get; set; }
 public string SearchString { get; set; } = string.Empty;
 public decimal MaxPrice { get; set; } = 10000;
}

Ajustar a ação do controlador para preencher o modelo de visualização e passá-lo para a visualização. A visualização usa e acessa propriedades de acordo.

Etapa 8: Implementação da Validação

O ASP.NET Core MVC fornece validação tanto do lado do servidor como do lado do cliente através de anotações de dados. Adicione , , e atributos personalizados. Na visão , o exibe mensagens de erro. O atributo na ação POST garante que apenas as submissões de formulários genuínas são processadas.

Para lógica de validação personalizada, implemente no seu modelo ou crie uma classe de validação separada. A documentação oficial de validação ASP.NET Core cobre estes padrões em detalhe.

Etapa 9: Injecção de dependência em controladores

Em vez de dados de codificação dura, você pode injetar serviços (como um repositório ou contexto de banco de dados) no construtor do controlador. Isso promove acoplamento solto e testabilidade.

public class ProductsController : Controller
{
 private readonly IProductRepository _repository;

 public ProductsController(IProductRepository repository)
 {
 _repository = repository;
 }

 public IActionResult Index()
 {
 var products = _repository.GetAll();
 return View(products);
 }
}

Registre o repositório em :

builder.Services.AddScoped<IProductRepository, ProductRepository>();

O método já registra controladores para DI. Este padrão torna sua aplicação mais limpa e mantendível. Veja Guia de Injeção de Dependência da Microsoft para mais.

Passo 10: Trabalhar com layouts e visões parciais

Os layouts compartilhados (por exemplo, ]) definem a estrutura geral da página. Para personalizar, modifique o em . Você pode definir seções, ou usar visualizações parciais para componentes de UI reutilizáveis, como navegação, rodapés ou renderizações de cartões de produto.

Vista parcial do exemplo :

@model Product
<div class="card">
 <div class="card-body">
 <h5 class="card-title">@Model.Name</h5>
 <p class="card-text">Price: @Model.Price.ToString("C")</p>
 <a asp-action="Details" asp-route-id="@Model.Id" class="btn btn-primary">Details</a>
 </div>
</div>

Inclui-o em qualquer ponto de vista com .

Etapa 11: Tratamento de Erros e Códigos de Estado

Os controladores devem lidar com erros graciosamente. Use os blocos ou um manipulador de exceção global através do middleware. Devolva códigos de estado HTTP apropriados:

  • para 404
  • para 400
  • para erros de servidor.

Você também pode adicionar uma visão de erro personalizada: ] já está incluído no modelo. Defina em para redirecionar as exceções na produção.

Passo 12: Testando a aplicação MVC

O teste é crítico. Use o xUnit e o pacote para escrever testes de integração. Exemplo para a ação :

public class ProductsControllerTests : IClassFixture<WebApplicationFactory<Program>>
{
 private readonly HttpClient _client;

 public ProductsControllerTests(WebApplicationFactory<Program> factory)
 {
 _client = factory.CreateClient();
 }

 [Fact]
 public async Task Index_ReturnsSuccessAndCorrectContentType()
 {
 var response = await _client.GetAsync("/products");
 response.EnsureSuccessStatusCode();
 Assert.Equal("text/html; charset=utf-8",
 response.Content.Headers.ContentType.ToString());
 }
}

Unidade teste o controlador com serviços simulados para isolar a lógica. ASP.NET Documentação de teste principal fornece extensos exemplos.

Melhores Práticas e Dicas Avançadas

  • Mantenha os controladores finos: A lógica empresarial pertence aos serviços/repositórios, não aos métodos de ação.
  • Use modelos de visualização: Evite passar modelos de domínio diretamente para visualizações; use modelos de visualização dedicados para moldar dados conforme necessário.
  • Aproveite os ajudantes de tags: Eles tornam o HTML mais limpo e reduzem erros na vinculação de formulários.
  • Permitindo validação do lado do cliente : Incluir ] e pacotes (já em ]]).
  • Use ações assync para operações com I/O: ] com .
  • Secure sua aplicação: Use sempre HTTPS, tokens anti-falsificação em formulários POST e autorização baseada em funções via .

Conclusão

A implementação da arquitetura MVC no ASP.NET Core oferece uma base sólida para construir aplicações web organizadas, testáveis e mantendíveis. Ao separar modelos, visualizações e controladores, você pode trabalhar em cada componente de forma independente e escalar sua aplicação com confiança. Os passos neste guia fornecem uma completa caminhada da criação do projeto para padrões prontos para produção. Comece com um projeto simples, então adicione incrementalmente integração de banco de dados, autenticação e recursos avançados.O site oficial ASP.NET Core MVC overview] é um excelente recurso seguinte à medida que você aprofunda seu conhecimento.