Is there a recommended way to use the new
nameof()
expression in ASP.NET MVC for controller names?
Url.Action("ActionName", "Home") <------ works
vs
Url.Action(nameof(ActionName), nameof(HomeController)) <----- doesn't work
obviously it doesn't work because of nameof(HomeController) converts to "HomeController" and what MVC needs is just "Home".
I like James' suggestion of using an extension method. There is just one problem: although you're using nameof()
and have eliminated magic strings, there's still a small issue of type safety: you're still working with strings. As such, it is very easy to forget to use the extension method, or to provide an arbitrary string that isn't valid (e.g. mistyping the name of a controller).
I think we can improve James' suggestion by using a generic extension method for Controller, where the generic parameter is the target controller:
public static class ControllerExtensions
{
public static string Action<T>(this Controller controller, string actionName)
where T : Controller
{
var name = typeof(T).Name;
string controllerName = name.EndsWith("Controller")
? name.Substring(0, name.Length - 10) : name;
return controller.Url.Action(actionName, controllerName);
}
}
The usage is now much cleaner:
this.Action<HomeController>(nameof(ActionName));