C# 从控制器内获取控制器和动作名称?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18248547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get controller and action name from within controller?
提问by Alex
For our web application I need to save the order of the fetched and displayed items depending on the view - or to be precise - the controller and action that generated the view (and the user id of course, but that's not the point here).
对于我们的 Web 应用程序,我需要根据视图保存获取和显示的项目的顺序 - 或者准确地说 - 生成视图的控制器和操作(当然还有用户 ID,但这不是这里的重点)。
Instead of just giving an identifier myself in each controller action (in order to use it for some view-dependant sorting of DB outputs), I thought that it would be safer and easier to create this identifier automatically from the controller and action method it gets called from.
与其只是在每个控制器操作中自己提供一个标识符(以便将其用于某些与视图相关的 DB 输出排序),我认为从控制器和它获取的操作方法自动创建此标识符会更安全、更容易叫自。
How can I get the name of the controller and action from within the action method in a controller? Or do I need reflection for that? I guess it's pretty easy, thanks in advance!
如何从控制器的操作方法中获取控制器和操作的名称?或者我需要反思吗?我想这很容易,在此先感谢!
采纳答案by Andrei
string actionName = this.ControllerContext.RouteData.Values["action"].ToString();
string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();
回答by sonjz
Might be useful. I needed the action in the constructorof the controller, and it appears at this point of the MVC lifecycle, this
hasn't initialized, and ControllerContext = null
. Instead of delving into the MVC lifecycle and finding the appropriate function name to override, I just found the action in the RequestContext.RouteData
.
可能有用。我需要控制器构造函数中的操作,它出现在 MVC 生命周期的这个点上,this
尚未初始化,并且ControllerContext = null
. 我没有深入研究 MVC 生命周期并找到要覆盖的适当函数名称,而是在RequestContext.RouteData
.
But in order to do so, as with any HttpContext
related uses in the constructor, you have to specify the full namespace, because this.HttpContext
also hasn't been initialized. Luckily, it appears System.Web.HttpContext.Current
is static.
但是为了做到这一点,与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
}
NOTE: likely not the most supported way to access all properties in HttpContext, but for RequestContext and Session it appears to work fine in my application.
注意:可能不是访问 HttpContext 中所有属性的最受支持的方式,但对于 RequestContext 和 Session 它似乎在我的应用程序中工作正常。
回答by Chris Ballance
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();
}
}
回答by John Bubriski
Here are some extension methods for getting that information (it also includes the ID):
以下是获取该信息的一些扩展方法(它还包括 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;
}
}
Usage:
用法:
@Html.Controller();
@Html.Action();
@Html.Id();
回答by MstfAsan
You can get controller name or action name from action like any variable. They are just special (controller and action)and already defined so you do not need to do anything special to get them except telling you need them.
您可以像任何变量一样从操作中获取控制器名称或操作名称。它们只是特殊的(控制器和动作)并且已经定义,所以你不需要做任何特殊的事情来获得它们,除非告诉你需要它们。
public string Index(string controller,string action)
{
var names=string.Format("Controller : {0}, Action: {1}",controller,action);
return names;
}
Or you can include controller , action in your models to get two of them and your custom data.
或者您可以在模型中包含 controller 、 action 以获取其中两个和您的自定义数据。
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;
}
回答by user3563149
This is what I have so far:
这是我到目前为止:
var actionName = filterContext.ActionDescriptor.ActionName;
var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
回答by joepour
This seems to work nicely for me (so far), also works if you are using attribute routing.
这对我来说似乎很好用(到目前为止),如果您使用属性路由也适用。
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");
}
}
回答by adie wong
回答by Vadim Ovchinnikov
To remove need for ToString()
call use
消除ToString()
呼叫使用的需要
string actionName = ControllerContext.RouteData.GetRequiredString("action");
string controllerName = ControllerContext.RouteData.GetRequiredString("controller");
回答by Kurkula
Add this to your base controller inside GetDefaults() method
将此添加到 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;
}
Implement your controllers to Basecontroller
将您的控制器实现到Basecontroller
Add a partial view _Breadcrumb.cshtml and add it in all required pages with @Html.Partial("_Breadcrumb")
添加局部视图 _Breadcrumb.cshtml 并使用 @Html.Partial("_Breadcrumb") 将其添加到所有必需的页面中
_Breadcrumb.cshtml
_Breadcrumb.cshtml
<span>
<a href="../@ViewData["controllerName"]">
@ViewData["controllerName"]
</a> > @ViewData["actionName"]
</span>