繁体   English   中英

C# 中是否有用于 MVC 控制器的 nameof() 运算符?

[英]Is there a nameof() operator for MVC controllers in C#?

新引入的nameof运算符有助于使我的代码成为我的“类型”。

代替

return RedirectToAction("Edit");

我们可以写

return RedirectToAction(nameof(Edit));

但是要获取控制器的名称并不是那么简单,因为我们有一个Controller后缀。 只是想知道我是否想要一个

return RedirectToAction(nameof(Index), controllernameof(Home));

代替

return RedirectToAction("Index", "Home");

我们如何实现controllernameof运算符?

也许像下面这样的扩展方法会满足您的需求:

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

您可以像这样调用:

return RedirectToAction(nameof(Index), typeof(HomeController).ControllerName());

不,没有这种可能。 您可能会感兴趣地改用T4MVC

T4MVC - 用于ASP.NET MVC应用程序的 T4 模板,它创建强类型帮助程序,在许多地方消除了文字字符串的使用。

例如代替

@Html.ActionLink("Dinner Details", "Details", "Dinners", new { id = Model.DinnerID }, null)

T4MVC让你写

@Html.ActionLink("Dinner Details", MVC.Dinners.Details(Model.DinnerID))

完全理解你不想使用魔法字符串的愿望! 在上面的评论和这篇文章之间 我已经开始在我的其他控制器继承的基本控制器中使用以下内容:

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

然后我使用:

 return RedirectToAction<HomeController>(a => nameof(a.Index));

 return RedirectToAction<HomeController>(a => nameof(a.Index), new { text= "searchtext" });

解决 XControllerController 案例的解决方案看起来更像是:

String nameStr = nameof(FlightControllerController);
nameStr = nameStr.Substring(0, nameStr.LastIndexOf("Controller"));

为了实现这种事情,我采用了@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;
        }
    }
}

要使用它,首先你必须添加“使用静态”

using static Helpers.ControllerHelper;

然后像这样在代码中使用它

var controllerName = Nameof<TestController>();

在 C# 8 及更高版本中,您可以使用范围运算符删除最后 10 个字符:

nameof(AccountController)[..^10]

10 可以用常量代替,如果你不喜欢简洁的话。

基于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" });


剃刀页面的扩展

public static string ControllerName(this string controllerName)
{
  return controllerName.Substring(0, controllerName.LastIndexOf("Controller"));
}

nameof(AccountController).ControllerName()

基于@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"));
    }
}

用法:

nameof(Controller).ControllerName()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM