Traditionally to reference an action and/or a controller in a Razor view the action/controller name is represented as a string as shown in the following code:
This means that some brittleness can be introduced into the application, for example if the name of the controller or action is changed these strings can become outdated and cause a runtime error.
The nameof operator introduced in C# 6.0 gets the (non fully qualified) name of the type passed to it. So for example nameof(HomeController) will return the string “HomeController”. The nameof operator can also be used with type members, for example nameof(HomeController.Index) will return the string “Index”.
The following code shows the use of nameof to get the action name programmatically without needing a magic string:
Now if the name of the HomeController.Index method is renamed, for example to HomeController.Index2, there will be a build time error: “'HomeController' does not contain a definition for 'Index'”.
The use of nameof can also be applied to the controller name:
The preceding code however causes errors, the link URL produced is “http://localhost:26663/HomeController/About” rather than the correct “http://localhost:26663/Home/About” (note the extra Controller text).
One way to rectify this would be to remove the word “Controller” from the string produced by nameof:
This technique introduces some code duplication, which could be addressed by creating a string extension method:
And then using this extension method:
Alternatively a static method could be created:
And then called from the view:
This technique may not work in all situations, for example if an action method is using the [ActionName] attribute:
In the preceding example, nameof(HomeController.Contact) will return the string “Contact” and the URL “http://localhost:26663/Home/Contact” wheras the correct URL should be “http://localhost:26663/Home/Contact2” because of the [ActionName("Contact2")] attribute.
Note that to get access to nameof, the view needs to be compiled with C# 6.0 language features enabled.