我不只是在每个控制器操作中自己给出一个标识符(以便将其用于数据库输出的某些依赖于视图的排序),我认为从控制器和操作方法自动创建此标识符会更安全、更容易接到电话。
如何从控制器的操作方法中获取控制器的名称和操作?还是我需要反思?
string actionName = this.ControllerContext.RouteData.Values["action"].ToString();
string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();
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();
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 来说,它似乎在我的应用程序中工作正常。
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();
}
}
@this.ViewContext.RouteData.Values["controller"].ToString();
var actionName = filterContext.ActionDescriptor.ActionName;
var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
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 进行测试。
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");
}
}
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>
(控制器和操作)并且已经定义,因此除了告诉您需要它们之外,您不需要做任何特殊的事情来获取它们。
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;
}
ToString()
呼叫使用的需要
string actionName = ControllerContext.RouteData.GetRequiredString("action");
string controllerName = ControllerContext.RouteData.GetRequiredString("controller");
将此覆盖方法添加到控制器
protected override void OnActionExecuting(ActionExecutingContext actionExecutingContext)
{
var actionName = actionExecutingContext.ActionDescriptor.ActionName;
var controllerName = actionExecutingContext.ActionDescriptor.ControllerDescriptor.ControllerName;
base.OnActionExecuting(actionExecutingContext);
}
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;
}
}
}