How to use C# nameof() with ASP.NET MVC Url.Action

Mikeon picture Mikeon · Dec 12, 2014 · Viewed 9.9k times · Source

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".

Answer

Gigi picture Gigi · Dec 14, 2014

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));