Introduction
Anyone who has worked with ASP.NET Core MVC has experienced the pain of renaming a controller and suddenly breaking every Url.Action and RedirectToAction call. A single typo in a string can silently generate invalid links. While Rider provides IntelliSense for these strings, we cannot assume every developer uses the same IDE.
To solve this, I created my own source generator called EndpointHelpers. It generates C# 14 extension properties on IUrlHelper using controller names, and then generates extension methods for all actions within each controller.
The article photo was taken by Joey Kyber.
What is EndpointHelpers
EndpointHelpers is a Roslyn source generator that creates strongly typed helpers for generating URLs and redirects. It generates:
IUrlHelperhelpers with methods per actionLinkGeneratorhelpers withGet{Action}Pathmethods, including overloads withHttpContext- Extensions on
IUrlHelperandLinkGeneratorto access the generated helpers - Typed redirect helpers for actions (e.g.,
RedirectToAction("Index")becomesthis.RedirectToIndex())
This NuGet package delivers only the generator and the generated code, with no runtime dependencies.
Before and after
Without the generator:
@Url.Action(action: "Details", controller: "Orders", values: new { orderId = 123, source = "dashboard" })
With the generator:
@Url.Orders.Details(123, "dashboard")
Installation
<ItemGroup>
<PackageReference Include="EndpointHelpers" Version="1.0.4" />
</ItemGroup>
dotnet add package EndpointHelpers
Quick start
Enable at the assembly level:
using EndpointHelpers;
[assembly: GenerateEndpointHelpers]
Or enable per controller/action:
using EndpointHelpers;
[GenerateEndpointHelpers]
public class OrdersController : Controller
{
public IActionResult Index() => View();
```
public IActionResult Details(int orderId, string? source) => View();
```
}
Typed redirects
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");
}
```
}
Scopes and filters
- Assembly:
[assembly: GenerateUrlHelper],[assembly: GenerateLinkGenerator],[assembly: GenerateRedirectToAction]or[assembly: GenerateEndpointHelpers] - Controller: the same attributes on the class
- Action: the same attributes on specific methods
To exclude, use:
[UrlHelperIgnore][LinkGeneratorIgnore][RedirectToActionIgnore][NonAction]
Conclusion
The main advantage is having strongly typed URLs instead of relying on magic strings. This allows safe refactoring and gives you full IntelliSense support to access all your endpoints directly from your IDE.
The repository is available on GitHub: https://www.github.com/gumbarros/EndpointHelpers. If you find it useful, consider starring the project.