Ответ 1
string actionName = this.ControllerContext.RouteData.Values["action"].ToString();
string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();
Для нашего веб-приложения мне нужно сохранить порядок выбранных и отображаемых элементов в зависимости от представления - или, если быть точным, - контроллера и действия, которые генерировали представление (и идентификатор пользователя, конечно, но это не точка здесь).
Вместо того, чтобы просто указывать идентификатор в каждом действии контроллера (чтобы использовать его для некоторой сортировки выходов DB, зависящей от вида), я думал, что было бы безопаснее и проще создавать этот идентификатор автоматически из контроллера и действия метод, из которого он вызван.
Как я могу получить имя контроллера и действия из метода действия в контроллере? Или мне нужно размышление? Я думаю, это довольно легко, спасибо заранее!
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();
Может быть полезно. Мне понадобилось действие в конструкторе конструктора контроллера, и он появляется в этой точке жизненного цикла 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();
}
}
Это то, что у меня есть до сих пор:
var actionName = filterContext.ActionDescriptor.ActionName;
var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
Вы можете получить имя контроллера или имя действия из действия, как любая переменная. Они просто специальные (контроллер и действие) и уже определены, поэтому вам не нужно делать ничего особенного, чтобы получить их, за исключением того, что вам нужно их.
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;
}
Кажется, что это хорошо работает для меня (пока), также работает, если вы используете маршрутизацию атрибутов.
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");
}
}
@this.ViewContext.RouteData.Values["controller"].ToString();
Чтобы удалить необходимость ToString()
использовать вызов
string actionName = ControllerContext.RouteData.GetRequiredString("action");
string controllerName = ControllerContext.RouteData.GetRequiredString("controller");
Добавьте это в свой базовый контроллер внутри метода 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.cshtml
<span>
<a href="../@ViewData["controllerName"]">
@ViewData["controllerName"]
</a> > @ViewData["actionName"]
</span>
Вот самый простой и практичный ответ на получение имени:
var actionName = RouteData.Values["controller"];
var controllerName = RouteData.Values["action"];
или
string actionName = RouteData.Values["controller"].ToString();
string controllerName = RouteData.Values["action"].ToString();
Код выше тестов с asp.net mvc 5.
Используйте заданные строки в имени OnActionExecuting for Action и Controller.
string actionName = this.ControllerContext.RouteData.Values [ "action" ]. ToString();
string controllerName = this.ControllerContext.RouteData.Values [ "controller" ]. ToString();
Почему бы не сделать что-то более простое?
Просто вызовите Request.Path
, он вернет строку, разделенную "/"
а затем вы можете использовать .Split('/')[1]
для получения имени контроллера.