在控制器内获取控制器和动作名称?

211

为了我们的web应用程序,我需要根据视图-或者更准确地说是生成视图的控制器和操作(以及用户id,但这不是重点)来保存获取和显示项的顺序。

我想,与其在每个控制器动作中自己提供一个标识符(以便用于某些视图相关的数据库输出排序),不如自动从调用它的控制器和动作方法中创建此标识符,这样更安全、更容易实现。

如何在控制器的操作方法内获取控制器和操作的名称?或者需要反射吗?


1
反射会给你处理操作的方法名称,但是你可能更喜欢安德烈的代码返回的操作名称。 - citykid
我基本上只需要一个明确的标识符来标识每个提供视图的操作,所以两种方式都可以胜任。但你是对的,Andrei的答案肯定更优雅。 - Rob
@citykid除了大小写和类名后缀“Controller”之外,它们是否有其他不同的用法? - John
@John,ActionNameAttribute允许C#方法具有任何操作名称:http://msdn.microsoft.com/en-us/library/system.web.mvc.actionnameattribute%28v=vs.118%29.aspx - citykid
@citykid 哦,好的。既然你可以在操作方法上使用“Route”属性指定路由,那么这种功能有点过时了,我猜是吗?另外,重命名控制器也是可能的吗? - John
显示剩余2条评论
14个回答

1
为了避免需要调用ToString(),可以使用以下方法。
string actionName = ControllerContext.RouteData.GetRequiredString("action");
string controllerName = ControllerContext.RouteData.GetRequiredString("controller");

1
你可以像访问任何变量一样从操作中获取控制器名称或操作名称。它们只是特殊的(控制器和操作),已经定义好了,所以你不需要做任何特殊的操作来获取它们,除了告诉程序你需要它们。
public string Index(string controller,string action)
   {
     var names=string.Format("Controller : {0}, Action: {1}",controller,action);
     return names;
   }

或者您可以在模型中包含控制器和操作来获取两者和您的自定义数据。

public class DtoModel
    {
        public string Action { get; set; }
        public string Controller { get; set; }
        public string Name { get; set; }
    }

public string Index(DtoModel baseModel)
    {
        var names=string.Format("Controller : {0}, Action: {1}",baseModel.Controller,baseModel.Action);
        return names;
    }

1
我知道这是一个老问题,但也许这可以帮助到某人。除了John B的答案之外,这是.NET 6.0或更高版本的解决方案。
namespace Microsoft.AspNetCore.Mvc.Rendering
    {
    public static class HtmlRequestHelper
    {
        public static string Id(this IHtmlHelper htmlHelper)
        {
            var routeValues = htmlHelper.ViewContext.RouteData.Values;

            if (routeValues.ContainsKey("id"))
                return (string)routeValues["id"];
            else if (htmlHelper.ViewContext.RouteData.Values["id"] != null)
                return htmlHelper.ViewContext.RouteData.Values["id"].ToString();

            return string.Empty;
        }

        public static string Controller(this IHtmlHelper htmlHelper)
        {
            var routeValues = htmlHelper.ViewContext.RouteData.Values;

            if (routeValues.ContainsKey("controller"))
                return (string)routeValues["controller"];

            return string.Empty;
        }

        public static string Action(this IHtmlHelper htmlHelper)
        {
            var routeValues = htmlHelper.ViewContext.RouteData.Values;

            if (routeValues.ContainsKey("action"))
                return (string)routeValues["action"];

            return string.Empty;
        }
    }
}

-8
为什么不使用更简单的方法呢?
只需调用Request.Path,它将返回由“/”分隔的字符串。
然后您可以使用.Split('/')[1]来获取控制器名称。

enter image description here


1
使用您的代码,子级应用程序将被简单地忽略(例如:http://www.example.com/sites/site1/controllerA/actionB/)。MVC提供了一堆API用于路由,所以为什么您需要再次解析URL? - T-moty
为什么要重新发明轮子,而且还是一个质量不佳的新版本呢?这并不适用于所有情况。 - jstuardo
除了子文件夹之外,真正的问题是您可以自定义路由,因此它们不总是controller/action - drzaus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接