Risposte:
Utilizzare ViewContext
e guardare la RouteData
raccolta per estrarre sia il controller che gli elementi di azione. Ma penso che l'impostazione di una variabile di dati che indichi il contesto dell'applicazione (ad es. "Editmode" o "error") anziché il controller / azione riduce l'accoppiamento tra le visualizzazioni e i controller.
In RC è anche possibile estrarre i dati del percorso come il nome del metodo di azione in questo modo
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"]
ViewContext.Controller.ValueProvider.GetValue("action").RawValue
+ variazioni
Per ottenere l'ID corrente in una vista:
ViewContext.RouteData.Values["id"].ToString()
Per ottenere il controller corrente:
ViewContext.RouteData.Values["controller"].ToString()
ViewContext.RouteData.Values.ContainsKey(<key>)
prima.
So che questa è una domanda più vecchia, ma l'ho vista e ho pensato che potresti essere interessato a una versione alternativa piuttosto che lasciare che la tua vista gestisca il recupero dei dati necessari per fare il suo lavoro.
Un modo più semplice secondo me sarebbe quello di sovrascrivere il metodo OnActionExecuting . Si è passati ad ActionExecutingContext che contiene il membro ActionDescriptor che è possibile utilizzare per ottenere le informazioni che si stanno cercando, ovvero ActionName e si può anche raggiungere ControllerDescriptor e contiene 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.
}
Spero che questo ti aiuti. Semmai, almeno mostrerà un'alternativa per chiunque altro venga dalla tua domanda.
Ho visto risposte diverse e ho trovato un aiutante di 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;
}
}
}
Quindi in View (o master / layout) puoi usarlo in questo modo (sintassi 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>
Spero che sia d'aiuto.
È possibile ottenere questi dati da RouteData di un ViewContext
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]
In MVC è necessario fornire a View tutti i dati, non consentire a View di raccogliere i propri dati, pertanto è possibile impostare la classe CSS nell'azione del controller.
ViewData["CssClass"] = "bold";
e scegli questo valore dal tuo ViewData nella tua vista
Voto per questo 2:
string currentActionName = ViewContext.RouteData.GetRequiredString("action");
e
string currentViewName = ((WebFormView)ViewContext.View).ViewPath;
È possibile recuperare sia il nome fisico della vista corrente sia l'azione che lo ha attivato. Può essere utile in pagine * .acmx parziali per determinare il contenitore host.
Estensione della risposta di Dale Ragan , il suo esempio di riutilizzo, crea una classe ApplicationController che deriva dal controller e, a sua volta, tutti gli altri controller derivano da quella classe ApplicationController anziché dal controller.
Esempio:
public class MyCustomApplicationController : Controller {}
public class HomeController : MyCustomApplicationController {}
Sul tuo nuovo ApplicationController crea una proprietà denominata ExecutingAction con questa firma:
protected ActionDescriptor ExecutingAction { get; set; }
E poi nel metodo OnActionExecuting (dalla risposta di Dale Ragan), è sufficiente assegnare ActionDescriptor a questa proprietà e puoi accedervi ogni volta che ne hai bisogno in uno dei tuoi controller.
string currentActionName = this.ExecutingAction.ActionName;
Sostituisci questa funzione nel tuo controller
protected override void HandleUnknownAction(string actionName)
{ TempData["actionName"] = actionName;
View("urViewName").ExecuteResult(this.ControllerContext);
}