web-dev-qa-db-fra.com

Comment puis-je renvoyer l'action en cours dans une vue ASP.NET MVC?

Je voulais définir une classe CSS dans ma page maître, qui dépend du contrôleur et de l'action en cours. Je peux accéder au contrôleur actuel via ViewContext.Controller.GetType().Name, mais comment puis-je obtenir l'action en cours (par exemple Index, Show etc.)?

288
buggs

Utilisez le ViewContext et examinez la collection RouteData pour extraire les éléments contrôleur et action. Mais je pense que définir une variable de données qui indique le contexte de l'application (par exemple, "editmode" ou "error") plutôt que le contrôleur/action réduit le couplage entre vos vues et les contrôleurs.

82
tvanfosson

Dans la télécommande, vous pouvez également extraire des données de routage telles que le nom de la méthode d’action, comme ceci:

ViewContext.Controller.ValueProvider["action"].RawValue
ViewContext.Controller.ValueProvider["controller"].RawValue
ViewContext.Controller.ValueProvider["id"].RawValue

Mise à jour pour MVC 3

ViewContext.Controller.ValueProvider.GetValue("action").RawValue
ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
ViewContext.Controller.ValueProvider.GetValue("id").RawValue

Mise à jour pour MVC 4

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

Mise à jour pour MVC 4.5

ViewContext.RouteData.Values["action"]
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["id"]
463
Christian Dalager

Pour obtenir l'identifiant actuel sur une vue:

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

Pour obtenir le contrôleur actuel:

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

Je sais que la question est ancienne, mais je l’ai vue et je pensais que vous pourriez être intéressé par une version alternative au lieu de laisser votre vue gérer la récupération des données dont elle a besoin pour faire son travail.

À mon avis, un moyen plus simple serait de remplacer la méthode OnActionExecuting . Vous êtes passé le ActionExecutingContext qui contient le membre ActionDescriptor que vous pouvez utiliser pour obtenir les informations que vous recherchez, qui est le nom d’action et vous pouvez également atteindre le ControllerDescriptor et le contient le 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.
}

J'espère que cela t'aides. Au moins, cela montrera au moins une alternative pour quiconque répond à votre question.

41
Dale Ragan

J'ai vu différentes réponses et j'ai trouvé un assistant de classe:

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

Donc dans View (ou master/layout), vous pouvez l'utiliser comme suit (syntaxe 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>

J'espère que ça aide.

17
Michael Vashchinsky

Vous pouvez obtenir ces données à partir de RouteData d'un ViewContext

ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]
13
Viacheslav Smityukh

Dans MVC, vous devez fournir à la vue toutes les données et ne pas le laisser collecter ses propres données. Vous pouvez donc définir la classe CSS dans l'action de votre contrôleur.

ViewData["CssClass"] = "bold";

et choisissez cette valeur dans ViewData dans votre vue

9
terjetyl

J'utilise ASP.NET MVC 4, et voici ce qui a fonctionné pour moi:

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

Ignorer cette fonction dans votre contrôleur

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

Étendre réponse de Dale Ragan , son exemple de réutilisation, crée une classe ApplicationController dérivée de Controller et fait en sorte que tous vos autres contrôleurs dérivent de cette classe ApplicationController plutôt que de Controller.

Exemple:

public class MyCustomApplicationController : Controller {}

public class HomeController : MyCustomApplicationController {}

Sur votre nouveau ApplicationController, créez une propriété nommée ExecutingAction avec cette signature:

protected ActionDescriptor ExecutingAction { get; set; }

Et ensuite, dans la méthode OnActionExecuting (d'après la réponse de Dale Ragan), associez simplement ActionDescriptor à cette propriété et vous pourrez y accéder à tout moment, dans n'importe lequel de vos contrôleurs.

string currentActionName = this.ExecutingAction.ActionName;
0
RunnerRick