代码之家  ›  专栏  ›  技术社区  ›  Intellectual Gymnastics Lover

用于获取不带后缀的控制器名称的扩展方法

  •  0
  • Intellectual Gymnastics Lover  · 技术社区  · 5 年前

    我不想重复下面的内容

    nameof(HomeController).Replace(nameof(Controller), string.Empty)
    

    每次我需要提供不带后缀“controller”的控制器名称时。

    有什么优雅的方法可以简化吗?我试图创建一个扩展方法,如下所示,但我不知道如何从cshtml视图中获取相关控制器的实例。

    using Microsoft.AspNetCore.Mvc;
    
    namespace WebApplication1
    {
        public static class Utilities
        {
            public static string BareName(this Controller controller)
            {
                return nameof(controller.GetType).Replace(nameof(Controller), string.Empty);
            }
        }
    }
    

    例如,我想在视图页面中调用以下内容。

    @Html.ActionLink("something", nameof(HomeController.someaction), nameof(HomeController).Replace(nameof(Controller), string.Empty))
    
    3 回复  |  直到 5 年前
        1
  •  6
  •   Henk Mollema    5 年前

    您可以在上创建一个单独的扩展方法 ActionContext 它从 ActionDescriptor

    public static string GetControllerName(this ActionContext actionContext)
    {
        return (actionContext.ActionDescriptor as ControllerActionDescriptor)?.ControllerName;
    }
    

    在这种情况下,不需要从字符串中修剪“控制器”部分。在您的视图中这样称呼它:

    var controllerName = ViewContext.GetControllerName();
    
        2
  •  5
  •   Camilo Terevinto Chase R Lewis    5 年前

    public static string BareName<T>() where T: Controller
    {
        return typeof(T).Name.Replace(nameof(Controller), string.Empty);
    }
    

    然后,您可以像这样使用它:

    @Html.ActionLink("something", nameof(HomeController.someaction), Utilities.BareName<HomeController>())
    

    我仍然不知道为什么微软没有把它作为ASP.NET核心包的一部分。。。

        3
  •  3
  •   Chris Pratt    5 年前

    如果您在视图中,只需使用 ViewContext.RouteData.Values["controller"] .

    更新(基于编辑的问题)

    所以,是的,在你真正想要实现什么之前,还不清楚。基本上,您希望能够指定如下方法的控制器/操作参数 Html.Action 不使用硬编码字符串。就扩展方法而言,最好的选择是 IHtmlHelper 扩展,如:

    public static class IHtmlHelperExtensions
    {
        public static string GetControllerName<TController>(this IHtmlHelper helper)
            where TController : Controller
        {
            return typeof(TController).GetName().Replace("Controller", "");
        }
    }
    

    然后您可以使用它,如:

    Html.GetControllerName<HomeController>()
    

    然而,这对我来说仍然很笨拙。老实说,如果您希望避免硬编码,我建议您命名路由并使用静态类来存放这些名称:

    public static class RouteNames
    {
        public const string Home = "Home";
    }
    

    public class HomeController : Controller
    {
        [HttpGet("", Name = RouteNames.Home)]
        public IActionResult Index() => View();
    }
    

    最后:

    @Html.RouteLink(RouteNames.Home, RouteNames.Home)
    

    <a asp-route="@RouteNames.Home">@RouteNames.Home</a>
    
        4
  •  1
  •   Majid    5 年前

    如果要在视图或控制器中获取控制器、操作或区域名称,请使用以下选项:

    您只需要引用 ViewContext HttpContext IHtmlHelper 对象:

    ////////////////////////////////
    // with an IHtmlHelper object //
    ////////////////////////////////
    var request = htmlHelper.ViewContext.HttpContext.Request;
    var controllerName = request.RouteValues["controller"].ToString();
    var actionName = request.RouteValues["action"].ToString();
    // if area exists
    var areaName = request.RouteValues["area"].ToString();
    
    //////////////////////////////////
    // with an `ViewContext` object //
    //////////////////////////////////
    var controllerName = ViewContext.RouteData.Values["controller"].ToString();
    var actionName = ViewContext.RouteData.Values["action"].ToString();
    // if area exists
    var areaName = ViewContext.RouteData.Values["area"].ToString();
    

    public static class IHtmlHelperExtensions
    {
        public static string GetControllerName(this IHtmlHelper htmlHelper) =>
            htmlHelper.ViewContext.RouteData.Values["controller"].ToString();
    }
    
        5
  •  0
  •   Make Makeluv    5 年前
    [HttpGet]
    public IActionResult Get([FromRoute]string controller)
    { 
        //controller will be Controller name without suffix "Controller".
    }