从控制器内获取控制器和操作名称?

问题描述 投票:0回答:14
对于我们的 Web 应用程序,我需要根据视图保存获取和显示项目的顺序 - 或者准确地说 - 生成视图的控制器和操作(当然还有用户 ID,但这不是这里的重点) .

我不只是在每个控制器操作中自己给出一个标识符(以便将其用于数据库输出的某些依赖于视图的排序),我认为从控制器和操作方法自动创建此标识符会更安全、更容易接到电话。

如何从控制器的操作方法中获取控制器的名称和操作?还是我需要反思?

c# asp.net-mvc controller action
14个回答
398
投票
string actionName = this.ControllerContext.RouteData.Values["action"].ToString(); string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();
    

75
投票
以下是获取该信息的一些扩展方法(还包括 ID):

public static class HtmlRequestHelper { public static string Id(this HtmlHelper htmlHelper) { var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values; if (routeValues.ContainsKey("id")) return (string)routeValues["id"]; else if (HttpContext.Current.Request.QueryString.AllKeys.Contains("id")) return HttpContext.Current.Request.QueryString["id"]; return string.Empty; } public static string Controller(this HtmlHelper htmlHelper) { var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values; if (routeValues.ContainsKey("controller")) return (string)routeValues["controller"]; return string.Empty; } public static string Action(this HtmlHelper htmlHelper) { var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values; if (routeValues.ContainsKey("action")) return (string)routeValues["action"]; return string.Empty; } }
用途:

@Html.Controller(); @Html.Action(); @Html.Id();
    

24
投票
可能有用。我需要控制器的

constructor 中的操作,它出现在 MVC 生命周期的此时,this

 尚未初始化,并且 
ControllerContext = null
。我没有深入研究 MVC 生命周期并找到要覆盖的适当函数名称,而是只是在 
RequestContext.RouteData
 中找到了操作。

但是为了做到这一点,与构造函数中任何与

HttpContext

 相关的使用一样,您必须指定完整的命名空间,因为 
this.HttpContext
 也尚未初始化。幸运的是,看起来 
System.Web.HttpContext.Current
 是静态的。

// controller constructor public MyController() { // grab action from RequestContext string action = System.Web.HttpContext.Current.Request.RequestContext.RouteData.GetRequiredString("action"); // grab session (another example of using System.Web.HttpContext static reference) string sessionTest = System.Web.HttpContext.Current.Session["test"] as string }

注意:可能不是访问 HttpContext 中所有属性的最受支持的方法,但对于 RequestContext 和 Session 来说,它似乎在我的应用程序中工作正常。


13
投票
var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values; if (routeValues != null) { if (routeValues.ContainsKey("action")) { var actionName = routeValues["action"].ToString(); } if (routeValues.ContainsKey("controller")) { var controllerName = routeValues["controller"].ToString(); } }
    

6
投票
@this.ViewContext.RouteData.Values["controller"].ToString();
    

5
投票
这是我到目前为止所拥有的:

var actionName = filterContext.ActionDescriptor.ActionName; var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
    

5
投票
这是获取名字最简单、最实用的答案:

var actionName = RouteData.Values["action"]; var controllerName = RouteData.Values["controller"];

或者

string actionName = RouteData.Values["action"].ToString(); string controllerName = RouteData.Values["controller"].ToString();

上面的代码使用 asp.net mvc 5 进行测试。


2
投票
这对我来说似乎很有效(到目前为止),如果您使用属性路由也同样有效。

public class BaseController : Controller { protected string CurrentAction { get; private set; } protected string CurrentController { get; private set; } protected override void Initialize(RequestContext requestContext) { this.PopulateControllerActionInfo(requestContext); } private void PopulateControllerActionInfo(RequestContext requestContext) { RouteData routedata = requestContext.RouteData; object routes; if (routedata.Values.TryGetValue("MS_DirectRouteMatches", out routes)) { routedata = (routes as List<RouteData>)?.FirstOrDefault(); } if (routedata == null) return; Func<string, string> getValue = (s) => { object o; return routedata.Values.TryGetValue(s, out o) ? o.ToString() : String.Empty; }; this.CurrentAction = getValue("action"); this.CurrentController = getValue("controller"); } }
    

2
投票
将其添加到 GetDefaults() 方法内的基本控制器

protected override void OnActionExecuting(ActionExecutingContext filterContext) { GetDefaults(); base.OnActionExecuting(filterContext); } private void GetDefaults() { var actionName = filterContext.ActionDescriptor.ActionName; var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; }

将您的控制器实现到

Basecontroller

添加部分视图 _Breadcrumb.cshtml 并将其添加到所有必需的页面中 @Html.Partial("_Breadcrumb")

_Breadcrumb.cshtml

<span> <a href="../@ViewData["controllerName"]"> @ViewData["controllerName"] </a> > @ViewData["actionName"] </span>
    

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
投票
要消除对

ToString()

 呼叫使用的需要

string actionName = ControllerContext.RouteData.GetRequiredString("action"); string controllerName = ControllerContext.RouteData.GetRequiredString("controller");
    

1
投票
试试这个代码

将此覆盖方法添加到控制器

protected override void OnActionExecuting(ActionExecutingContext actionExecutingContext) { var actionName = actionExecutingContext.ActionDescriptor.ActionName; var controllerName = actionExecutingContext.ActionDescriptor.ControllerDescriptor.ControllerName; base.OnActionExecuting(actionExecutingContext); }
    

0
投票
我知道这是一个老问题,但这也许对某人有帮助。作为对 John B 答案的补充,这是 .NET 6.0 或更高版本的解决方案。

namespace Microsoft.AspNetCore.Mvc.Rendering
{
公共静态类 HtmlRequestHelper
{
公共静态字符串Id(此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]

 获取控制器名称。

© www.soinside.com 2019 - 2024. All rights reserved.