Introdução
Quem usa ASP.NET Core MVC já sofreu renomeando uma controller e todos Url.Action e RedirectToAction pararem de funcionar, ou até mesmo esqueceu um caractere e o link gerado não funcionou. O Rider por exemplo fornece intellisense para estas strings, mas não podemos contar que todos desenvolvedores usem a mesma IDE.
Para isto, resolvi este problema criando meu próprio source generator chamado EndpointHelpers. Ele cria propriedades de extensão do C# 14 no IUrlHelper com o nome das Controllers e em seguida gera métodos de extensão com todas Actions desta controller.
A foto do artigo foi tirada por Joey Kyber.
O que é o EndpointHelpers
O EndpointHelpers é um source generator em Roslyn que cria helpers fortemente tipados para gerar URLs e redirects. Ele gera:
- Helpers de
IUrlHelpercom métodos por action - Helpers de
LinkGeneratorcom métodosGet{Action}Path, incluindo overloads comHttpContext - Extensões em
IUrlHelpereLinkGeneratorpara acessar os helpers - Helpers de redirect para actions (ex.:
RedirectToAction("Index")virathis.RedirectToIndex())
Este NuGet entrega apenas o gerador e o código gerado, sem dependências em runtime.
Antes e depois
Sem o gerador:
@Url.Action(action: "Details", controller: "Orders", values: new { orderId = 123, source = "dashboard" })
Com o gerador:
@Url.Orders.Details(123, "dashboard")
Instalação
<ItemGroup>
<PackageReference Include="EndpointHelpers" Version="1.0.4" />
</ItemGroup>
dotnet add package EndpointHelpers
Quick start
Habilite no assembly:
using EndpointHelpers;
[assembly: GenerateEndpointHelpers]
Ou habilite por controller/action:
using EndpointHelpers;
[GenerateEndpointHelpers]
public class OrdersController : Controller
{
public IActionResult Index() => View();
public IActionResult Details(int orderId, string? source) => View();
}
Redirects tipados
public class OrdersController : Controller
{
public IActionResult Index() => View();
[GenerateRedirectToAction]
public IActionResult Details(int orderId, string? source) => View();
public IActionResult Save()
{
return this.RedirectToDetails(orderId: 123, source: "created");
}
}
Escopos e filtros
- Assembly:
[assembly: GenerateUrlHelper],[assembly: GenerateLinkGenerator],[assembly: GenerateRedirectToAction]ou[assembly: GenerateEndpointHelpers] - Controller: os mesmos atributos na classe
- Action: os mesmos atributos em métodos específicos
Para excluir, use:
[UrlHelperIgnore][LinkGeneratorIgnore][RedirectToActionIgnore][NonAction]
Conclusão
A grande vantagem é ter URLs fortemente tipadas, e não baseadas em strings mágicas. Assim você pode refatorar sem medo, e consegue também com o intellisense da IDE ter todos os seus endpoints na mão.
O repositório está no GitHub: https://www.github.com/gumbarros/EndpointHelpers. Não esqueça de deixar sua estrela para apoiar o projeto :)