'Is there a nameof() operator for MVC controllers in C#?
The newly introduced nameof
operator is useful in making my code my "typed".
Instead of
return RedirectToAction("Edit");
we can write
return RedirectToAction(nameof(Edit));
But for to get a controller's name is not that straightforward, because we have a Controller
suffix. Just want to know if I want to have a
return RedirectToAction(nameof(Index), controllernameof(Home));
to take the place of
return RedirectToAction("Index", "Home");
how can we implement the controllernameof
operator?
Solution 1:[1]
Maybe an extension method like the following would suit your needs:
public static class ControllerExtensions
{
public static string ControllerName(this Type controllerType)
{
Type baseType = typeof(Controller);
if (baseType.IsAssignableFrom(controllerType))
{
int lastControllerIndex = controllerType.Name.LastIndexOf("Controller");
if (lastControllerIndex > 0)
{
return controllerType.Name.Substring(0, lastControllerIndex);
}
}
return controllerType.Name;
}
}
Which you could invoke like so:
return RedirectToAction(nameof(Index), typeof(HomeController).ControllerName());
Solution 2:[2]
No, there is no such possibility. You might be intertested to use T4MVC
instead.
T4MVC
- a T4 template forASP.NET MVC
apps that creates strongly typed helpers that eliminate the use of literal strings in many places.e.g. instead of
@Html.ActionLink("Dinner Details", "Details", "Dinners", new { id = Model.DinnerID }, null)
T4MVC
lets you write@Html.ActionLink("Dinner Details", MVC.Dinners.Details(Model.DinnerID))
Solution 3:[3]
Totally understand your desire to not use magic strings! Between the comments above and this article. I've started using the following in a base controller which my other controllers inherit from:
public RedirectToRouteResult RedirectToAction<TController>(Expression<Func<TController, string>> expression, object routeValues)
{
if (!(expression.Body is ConstantExpression constant))
{
throw new ArgumentException("Expression must be a constant expression.");
}
string controllerName = typeof(TController).Name;
controllerName = controllerName.Substring(0, controllerName.LastIndexOf("Controller"));
return RedirectToAction(constant.Value.ToString(), controllerName, routeValues);
}
public RedirectToRouteResult RedirectToAction<TController>(Expression<Func<TController, string>> expression)
{
return RedirectToAction(expression, null);
}
I then use :
return RedirectToAction<HomeController>(a => nameof(a.Index));
and
return RedirectToAction<HomeController>(a => nameof(a.Index), new { text= "searchtext" });
Solution 4:[4]
The solution that solves the case of the XControllerController would look more like:
String nameStr = nameof(FlightControllerController);
nameStr = nameStr.Substring(0, nameStr.LastIndexOf("Controller"));
Solution 5:[5]
public class BaseController : Controller
{
public RedirectToRouteResult RedirectToAction<T>(string ActionName, object routeValues) where T : BaseController
{
string controllerName = typeof(T).Name;
controllerName = controllerName.Substring(0, controllerName.LastIndexOf("Controller"));
return RedirectToAction(ActionName, controllerName, routeValues);
}
public RedirectToRouteResult RedirectToAction<T>(string ActionName) where T : BaseController
{
return RedirectToAction<T>(ActionName, null);
}
}
Used like so:
return RedirectToAction<AccountController>(nameof(AccountController.Login));
return RedirectToAction<AccountController>(nameof(AccountController.Login), new { text= "searchtext" });
Extension for razor page:
public static string ControllerName(this string controllerName)
{
return controllerName.Substring(0, controllerName.LastIndexOf("Controller"));
}
Which you can use like this:
nameof(AccountController).ControllerName()
Solution 6:[6]
To achieve this kind of thing, I took @stephen.vakil's answer, merged with @huysentruitw's answer and wrote this:
namespace Helpers
{
public static class ControllerHelper
{
public static string Nameof<TController>() where TController : Controller
{
var name = typeof(TController).Name;
var indexOfControllerText = name.LastIndexOf("Controller");
if (indexOfControllerText > 0)
{
return name.Substring(0, indexOfControllerText);
}
return name;
}
}
}
To use this, first you have to add "using static"
using static Helpers.ControllerHelper;
And then use it in the code like this
var controllerName = Nameof<TestController>();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | stephen.vakil |
Solution 2 | Dmitry Pavlov |
Solution 3 | |
Solution 4 | Harold Blankenship |
Solution 5 | CarenRose |
Solution 6 | bafsar |