[英]Is there a nameof() operator for MVC controllers in C#?
The newly introduced nameof
operator is useful in making my code my "typed".新引入的
nameof
运算符有助于使我的代码成为我的“类型”。
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.但是要获取控制器的名称并不是那么简单,因为我们有一个
Controller
后缀。 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?我们如何实现
controllernameof
运算符?
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());
No, there is no such possibility.不,没有这种可能。 You might be intertested to use
T4MVC
instead.您可能会感兴趣地改用
T4MVC
。
T4MVC
- a T4 template forASP.NET MVC
apps that creates strongly typed helpers that eliminate the use of literal strings in many places.T4MVC
- 用于ASP.NET MVC
应用程序的 T4 模板,它创建强类型帮助程序,在许多地方消除了文字字符串的使用。eg instead of
例如代替
@Html.ActionLink("Dinner Details", "Details", "Dinners", new { id = Model.DinnerID }, null)
T4MVC
lets you writeT4MVC
让你写@Html.ActionLink("Dinner Details", MVC.Dinners.Details(Model.DinnerID))
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" });
The solution that solves the case of the XControllerController would look more like:解决 XControllerController 案例的解决方案看起来更像是:
String nameStr = nameof(FlightControllerController);
nameStr = nameStr.Substring(0, nameStr.LastIndexOf("Controller"));
To achieve this kind of thing, I took @stephen.vakil's answer , merged with @huysentruitw's answer and wrote this:为了实现这种事情,我采用了@stephen.vakil 的答案,与@huysentruitw 的答案合并并写下了这个:
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>();
In C# 8 and later you can use the range operator to remove the last 10 chars:在 C# 8 及更高版本中,您可以使用范围运算符删除最后 10 个字符:
nameof(AccountController)[..^10]
The 10 can be replaced with a constant, if you're not into the whole brevity thing. 10 可以用常量代替,如果你不喜欢简洁的话。
Based on Jon Ryan 's answer基于Jon Ryan的回答
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);
}
}
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"));
}
nameof(AccountController).ControllerName()
Based on @Trương Quốc Khánh answer, I've modified the extension method by adding some checks:基于@Trương Quốc Khánh的回答,我通过添加一些检查修改了扩展方法:
public static class StringExtensions
{
public static string ControllerName(this string controllerName)
{
if (!controllerName.EndsWith("Controller") || controllerName == "Controller")
throw new ArgumentException($"{controllerName} is not a valid name for a Controller class");
return controllerName.Substring(0, controllerName.LastIndexOf("Controller"));
}
}
Usage:用法:
nameof(Controller).ControllerName()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.