Как я могу вернуть текущее действие в ASP.NET вид MVC?
Я хотел установить класс CSS на моей главной странице, которая зависит от текущего контроллера и действия. Я могу добраться до текущего контроллера через ViewContext.Controller.GetType().Name, но как мне получить текущее действие (например Index,Show etc.)?
11 ответов:
использовать
ViewContextи посмотрите наRouteDataколлекция для извлечения элементов контроллера и действия. Но я думаю, что установка некоторой переменной данных, которая указывает контекст приложения (например, "editmode" или "error"), а не контроллер/действие уменьшает связь между вашими представлениями и контроллерами.
в RC вы также можете извлечь данные маршрута, такие как имя метода действия, как это
ViewContext.Controller.ValueProvider["action"].RawValue ViewContext.Controller.ValueProvider["controller"].RawValue ViewContext.Controller.ValueProvider["id"].RawValue
обновление для MVC 3
ViewContext.Controller.ValueProvider.GetValue("action").RawValue ViewContext.Controller.ValueProvider.GetValue("controller").RawValue ViewContext.Controller.ValueProvider.GetValue("id").RawValueобновление для MVC 4
ViewContext.Controller.RouteData.Values["action"] ViewContext.Controller.RouteData.Values["controller"] ViewContext.Controller.RouteData.Values["id"]обновление для MVC 4.5
ViewContext.RouteData.Values["action"] ViewContext.RouteData.Values["controller"] ViewContext.RouteData.Values["id"]
чтобы получить текущий идентификатор в представлении:
ViewContext.RouteData.Values["id"].ToString()получить текущий контроллер:
ViewContext.RouteData.Values["controller"].ToString()
Я знаю, что это более старый вопрос, но я видел его, и я подумал, что вам может быть интересна альтернативная версия, чем позволить вашему представлению обрабатывать извлечение данных, необходимых для выполнения этой работы.
более простой способ, на мой взгляд, было бы переопределить OnActionExecuting метод. Вы прошли ActionExecutingContext С ActionDescriptor член, который вы можете использовать для получения информации, которую вы ищете, которая является ActionName и вы также можете добраться до ControllerDescriptor, и он содержит ControllerName.
protected override void OnActionExecuting(ActionExecutingContext filterContext) { ActionDescriptor actionDescriptor = filterContext.ActionDescriptor; string actionName = actionDescriptor.ActionName; string controllerName = actionDescriptor.ControllerDescriptor.ControllerName; // Now that you have the values, set them somewhere and pass them down with your ViewModel // This will keep your view cleaner and the controller will take care of everything that the view needs to do it's job. }надеюсь, что это помогает. Если что-нибудь, по крайней мере, это покажет альтернативу для любого другого, который приходит по вашему вопросу.
Я видел разные ответы и придумал помощника класса:
using System; using System.Web.Mvc; namespace MyMvcApp.Helpers { public class LocationHelper { public static bool IsCurrentControllerAndAction(string controllerName, string actionName, ViewContext viewContext) { bool result = false; string normalizedControllerName = controllerName.EndsWith("Controller") ? controllerName : String.Format("{0}Controller", controllerName); if(viewContext == null) return false; if(String.IsNullOrEmpty(actionName)) return false; if (viewContext.Controller.GetType().Name.Equals(normalizedControllerName, StringComparison.InvariantCultureIgnoreCase) && viewContext.Controller.ValueProvider.GetValue("action").AttemptedValue.Equals(actionName, StringComparison.InvariantCultureIgnoreCase)) { result = true; } return result; } } }Итак, в представлении (или мастер / макет) вы можете использовать его так (синтаксис Razor):
<div id="menucontainer"> <ul id="menu"> <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("home", "index", ViewContext)) { @:class="selected" }>@Html.ActionLink("Home", "Index", "Home")</li> <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("account","logon", ViewContext)) { @:class="selected" }>@Html.ActionLink("Logon", "Logon", "Account")</li> <li @if(MyMvcApp.Helpers.LocationHelper.IsCurrentControllerAndAction("home","about", ViewContext)) { @:class="selected" }>@Html.ActionLink("About", "About", "Home")</li> </ul> </div>надеюсь, что это помогает.
вы можете получить эти данные из RouteData ViewContext
ViewContext.RouteData.Values["controller"] ViewContext.RouteData.Values["action"]
в MVC вы должны предоставить представление со всеми данными, а не позволять представлению собирать свои собственные данные, поэтому вы можете установить класс CSS в своем действии контроллера.
ViewData["CssClass"] = "bold";и выберите это значение из ваших ViewData в вашем представлении
Я голосую за это 2:
string currentActionName = ViewContext.RouteData.GetRequiredString("action");и
string currentViewName = ((WebFormView)ViewContext.View).ViewPath;вы можете повторно использовать как физическое имя текущего представления, так и действие, которое его вызвало. Это может быть полезно в частичном *.страницы acmx для определения контейнера хоста.
Я использую ASP.NET MVC 4, и это то, что сработало для меня:
ControllerContext.Controller.ValueProvider.GetValue("controller").RawValue ControllerContext.Controller.ValueProvider.GetValue("action").RawValue
расширения ответ Дейла Рагана, его пример для повторного использования, создайте класс ApplicationController, который является производным от контроллера, и, в свою очередь, все ваши другие контроллеры являются производными от этого класса ApplicationController, а не контроллера.
пример:
public class MyCustomApplicationController : Controller {} public class HomeController : MyCustomApplicationController {}на Вашем новом ApplicationController создайте свойство с именем ExecutingAction с этой подписью:
protected ActionDescriptor ExecutingAction { get; set; }а затем в методе OnActionExecuting (от Дейла Рагана ответ), просто назначьте ActionDescriptor этому свойству, и вы можете получить к нему доступ всякий раз, когда вам это нужно в любом из ваших контроллеров.
string currentActionName = this.ExecutingAction.ActionName;
переопределить эту функцию в контроллере
protected override void HandleUnknownAction(string actionName) { TempData["actionName"] = actionName; View("urViewName").ExecuteResult(this.ControllerContext); }
Comments