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



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

459   11  

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

    Ничего не найдено.