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.)?
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.
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
ViewContext.Controller.ValueProvider.GetValue("action").RawValue
ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
ViewContext.Controller.ValueProvider.GetValue("id").RawValue
ViewContext.Controller.RouteData.Values["action"]
ViewContext.Controller.RouteData.Values["controller"]
ViewContext.Controller.RouteData.Values["id"]
ViewContext.RouteData.Values["action"]
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["id"]
Pour obtenir l'identifiant actuel sur une vue:
ViewContext.RouteData.Values["id"].ToString()
Pour obtenir le contrôleur actuel:
ViewContext.RouteData.Values["controller"].ToString()
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.
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.
Vous pouvez obtenir ces données à partir de RouteData d'un ViewContext
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]
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
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
Ignorer cette fonction dans votre contrôleur
protected override void HandleUnknownAction(string actionName)
{ TempData["actionName"] = actionName;
View("urViewName").ExecuteResult(this.ControllerContext);
}
É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;