AspNet.Mvc.TypedRouting
A collection of extension methods providing strongly typed routing and link generation for ASP.NET Core MVC projects.
Install / Use
/learn @ivaylokenov/AspNet.Mvc.TypedRoutingREADME
Resolving controller and action names for various purposes in ASP.NET MVC was always unreliable because the framework uses magic strings in its methods (for example Url.Action("Action", "Controller")). With the C# 6.0 nameof operator, the problem was partially solved. However, nameof cannot be used with various MVC Core features like ActionNameAttribute, AreaAttribute, RouteValueAttribute, IControllerModelConvention, IActionModelConvention, IParameterModelConvention and more. Here comes AspNet.Mvc.TypedRouting to the rescue!
This package gives you typed expression based routing and link generation in a ASP.NET Core MVC web application. Currently working with version 1.1.0.
For example:
// adding route to specific action
routes.Add("MyRoute/{id}", route => route.ToAction<HomeController>(a => a.Index()))
// generating action link
Html.ActionLink<HomeController>("Index", c => c.Index())
Installation
You can install this library using NuGet into your web project. There is no need to add any namespace usings since the package uses the default ones to add extension methods.
Install-Package AspNet.Mvc.TypedRouting
For other interesting packages check out:
- MyTested.AspNetCore.Mvc - fluent testing framework for ASP.NET Core MVC
- MyTested.HttpServer - fluent testing framework for remote HTTP servers
- MyTested.WebApi - fluent testing framework for ASP.NET Web API 2
- ASP.NET MVC 5 Lambda Expression Helpers - typed expression based link generation for ASP.NET MVC 5
How to use
Just add AddTypedRouting() after AddMvc into your Startup class:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddTypedRouting();
}
You can check the provided sample to see a working web application with this library.
To register a typed route into your application, add the following line:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddTypedRouting(routes =>
{
routes.Get("MyRoute/{id}", route => route.ToAction<HomeController>(a => a.Index(With.Any<int>())));
});
}
This will register route http://mysite.com/MyRoute/{id} to match 'HomeController', 'Index' action with any integer as 'id'. Full list of available methods:
// adding route to specific controller and action name taken from name of method
routes.Add("MyRoute/{action}", route => route.ToController<HomeController>());
// adding route to specific action without parameters
routes.Add("MyRoute/MyAction", route => route.ToAction<HomeController>(a => a.Index()));
// adding route to specific action with any parameters
// * With.Any<TParameter>() is just expressive sugar, you can pass any value
routes.Add("MyRoute/MyAction/{id}", route => route.ToAction<HomeController>(a => a.Index(With.Any<int>())));
// adding route with specific name
routes.Add("MyRoute/MyAction", route => route
.ToAction<HomeController>(a => a.Index())
.WithName("RouteName"));
// adding route with custom action constraint
routes.Add("MyRoute/MyAction", route => route
.ToAction<HomeController>(a => a.Index())
.WithActionConstraint(new MyCustomConstraint()));
// adding route to specific HTTP methods
routes.Add("MyRoute/MyAction", route => route
.ToAction<HomeController>(a => a.Index())
.ForHttpMethods("GET", "POST"));
// you can also specify methods without magic strings
routes.Get("MyRoute/MyAction", route => route.ToAction<HomeController>(a => a.Index()));
routes.Post("MyRoute/MyAction", route => route.ToAction<HomeController>(a => a.Index()));
routes.Put("MyRoute/MyAction", route => route.ToAction<HomeController>(a => a.Index()));
routes.Delete("MyRoute/MyAction", route => route.ToAction<HomeController>(a => a.Index()));
Additionally, you can use typed link generation:
// generating link without parameters - /Home/Index
urlHelper.Action<HomeController>(c => c.Index());
// generating link with parameters - /Home/Index/1
urlHelper.Action<HomeController>(c => c.Index(1));
// generating link with additional route values - /Home/Index/1?key=value
urlHelper.Action<HomeController>(c => c.Index(1), new { key = "value" });
// generating link where action needs parameters to be compiled, but you do not want to pass them - /Home/Index
// * With.No<TParameter>() is just expressive sugar, you can pass 'null' for reference types but it looks ugly
urlHelper.Action<HomeController>(c => c.Index(With.No<int>()));
All methods resolve all kinds of route changing features like ActionNameAttribute, AreaAttribute, RouteConstraintAttribute, IControllerModelConvention, IActionModelConvention, IParameterModelConvention and potentially others. The expressions use the internally created by the MVC framework ControllerActionDescriptor objects, which contain all route specific information.
Controller extension methods:
// uses the same controller in the expression and created object
controller.CreatedAtAction(c => c.Index(), someObject);
// uses the same controller in the expression, additional route values and created object
controller.CreatedAtAction(c => c.Index(), new { key = "value" }, someObject);
// uses another controller in the expression and created object
controller.CreatedAtAction<HomeController>(c => c.Index(), someObject);
// uses another controller in the expression, additional route values and created object
controller.CreatedAtAction<HomeController>(c => c.Index(), new { key = "value" }, someObject);
// uses route name, the same controller in the expression and created object
controller.CreatedAtRoute("RouteName", c => c.Index(), someObject);
// uses route name, the same controller in the expression, additional route values and created object
controller.CreatedAtRoute("RouteName", c => c.Index(), new { key = "value" }, someObject);
// uses route name, another controller in the expression and created object
controller.CreatedAtRoute<HomeController>("RouteName", c => c.Index(), someObject);
// uses route name, another controller in the expression, additional route values and created object
controller.CreatedAtRoute<HomeController>("RouteName", c => c.Index(), new { key = "value" }, someObject);
// uses the same controller in the expression to return redirect result
controller.RedirectToAction(c => c.Index());
// uses the same controller in the expression and additional route values to return redirect result
controller.RedirectToAction(c => c.Index(), new { key = "value" });
// uses another controller in the expression to return redirect result
controller.RedirectToAction<HomeController>(c => c.Index());
// uses another controller in the expression and additional route values to return redirect result
controller.RedirectToAction<HomeController>(c => c.Index(), new { key = "value" });
// uses the same controller in the expression to return permanent redirect result
controller.RedirectToActionPermanent(c => c.Index());
// uses the same controller in the expression and additional route values to return permanent redirect result
controller.RedirectToActionPermanent(c => c.Index(), new { key = "value" });
// uses another controller in the expression to return permanent redirect result
controller.RedirectToActionPermanent<HomeController>(c => c.Index());
// uses another controller in the expression and additional route values to return permanent redirect result
controller.RedirectToActionPermanent<HomeController>(c => c.Index(), new { key = "value" });
// uses route name, the same controller in the expression to return redirect result
controller.RedirectToRoute("RouteName", c => c.Index());
// uses route name, the same controller in the expression and additional route values to return redirect result
controller.RedirectToRoute("RouteName", c => c.Index(), new { key = "value" });
// uses route name, another controller in the expression to return redirect result
controller.RedirectToRoute<HomeController>("RouteName", c => c.Index());
// uses route name, another controller in the expression and additional route values to return redirect result
controller.RedirectToRoute<HomeController>("RouteName", c => c.Index(), new { key = "value" });
// uses route name, the same controller in the expression to return permanent redirect result
controller.RedirectToRoutePermanent("RouteName", c => c.Index());
// uses route name, the same controller in the expression and additional route values to return permanent redirect result
controller.RedirectToRoutePermanent("RouteName", c => c.Index(), new { key = "value" });
// uses route name, another controller in the expression to return permanent redirect result
controller.RedirectToRoutePermanent<HomeController>("RouteName", c => c.Index());
// uses route name, another controller in the expression and additional route values to return permanent redirect result
controller
Related Skills
node-connect
332.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
81.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
332.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
81.7kCommit, push, and open a PR
