Как я могу вернуть текущее действие в представлении ASP.NET MVC?

Я хотел установить класс CSS на моей главной странице, который зависит от текущего контроллера и действия. Я могу перейти к текущему контроллеру через ViewContext.Controller.GetType().Name, но как мне получить текущее действие (например, Index, Show и т.д.)?

Ответ 1

Используйте ViewContext и посмотрите на коллекцию RouteData, чтобы извлечь как контроллер, так и элементы действий. Но я думаю, что установка некоторой переменной данных, которая указывает контекст приложения (например, "editmode" или "ошибка" ), а не контроль/действие, уменьшает связь между вашими представлениями и контроллерами.

Ответ 2

В 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"]

Ответ 3

Чтобы получить текущий идентификатор в представлении:

ViewContext.RouteData.Values["id"].ToString()

Чтобы получить текущий контроллер:

ViewContext.RouteData.Values["controller"].ToString() 

Ответ 4

Я знаю, что это более старый вопрос, но я это видел, и я подумал, что вам может быть интересна альтернативная версия, чем позволить обработчику вида получить данные, необходимые для выполнения этой работы.

По-моему, проще было бы переопределить метод 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 job.
}

Надеюсь, это поможет. Во всяком случае, по крайней мере, это покажет альтернативу для любого другого, кто приходит по вашему вопросу.

Ответ 5

Я видел разные ответы и придумывал класс-помощник:

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;
        }
    }
}

Итак, в View (или master/layout) вы можете использовать его так (синтаксис 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>

Надеюсь, что это поможет.

Ответ 6

Вы можете получить эти данные из RouteData из ViewContext

ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]

Ответ 7

В MVC вы должны предоставить представление со всеми данными, не позволяя View собирать свои собственные данные, поэтому вы можете установить класс CSS в действие вашего контроллера.

ViewData["CssClass"] = "bold";

и выберите это значение из ViewData в представлении

Ответ 8

Я голосую за это 2:

string currentActionName = ViewContext.RouteData.GetRequiredString("action");

и

string currentViewName = ((WebFormView)ViewContext.View).ViewPath;

Вы можете получить как физическое имя текущего вида, так и действие, которое его вызвало. Для определения контейнера хоста может быть полезно на частичных страницах .acmx.

Ответ 9

Я использую ASP.NET MVC 4, и это помогло мне:

ControllerContext.Controller.ValueProvider.GetValue("controller").RawValue
ControllerContext.Controller.ValueProvider.GetValue("action").RawValue

Ответ 10

Расширение Dale Ragan answer, его пример для повторного использования, создайте класс ApplicationController, который является производным от Controller, и, в свою очередь, все остальные контроллеры получаются из этого класса ApplicationController, чем контроллер.

Пример:

public class MyCustomApplicationController : Controller {}

public class HomeController : MyCustomApplicationController {}

На вашем новом ApplicationController создайте свойство с именем ExecutingAction с этой сигнатурой:

protected ActionDescriptor ExecutingAction { get; set; }

И затем в методе OnActionExecuting (из ответа Dale Ragan) просто присвойте ActionDescriptor этому свойству, и вы можете получить к нему доступ, когда вам это нужно, в любом из ваших контроллеров.

string currentActionName = this.ExecutingAction.ActionName;

Ответ 11

Отменить эту функцию в контроллере

protected override void HandleUnknownAction(string actionName) 
{  TempData["actionName"] = actionName;
   View("urViewName").ExecuteResult(this.ControllerContext);
}