Respuestas:
Use ViewContext
y mire la RouteData
colección para extraer tanto el controlador como los elementos de acción. Pero creo que establecer alguna variable de datos que indique el contexto de la aplicación (por ejemplo, "modo de edición" o "error") en lugar de controlador / acción reduce el acoplamiento entre sus vistas y controladores.
En el RC también puede extraer datos de ruta como el nombre del método de acción como este
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
+ variaciones
Para obtener la identificación actual en una vista:
ViewContext.RouteData.Values["id"].ToString()
Para obtener el controlador actual:
ViewContext.RouteData.Values["controller"].ToString()
ViewContext.RouteData.Values.ContainsKey(<key>)
primero.
Sé que esta es una pregunta anterior, pero la vi y pensé que podría estar interesado en una versión alternativa que dejar que su vista maneje la recuperación de los datos que necesita para hacer su trabajo.
Una manera más fácil en mi opinión sería anular el método OnActionExecuting . Se le pasa el ActionExecutingContext que contiene el miembro ActionDescriptor que puede usar para obtener la información que está buscando, que es ActionName y también puede comunicarse con ControllerDescriptor y 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.
}
Espero que esto ayude. En todo caso, al menos mostrará una alternativa para cualquier otra persona que surja de su pregunta.
Vi diferentes respuestas y se me ocurrió un ayudante de clase:
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;
}
}
}
Entonces, en View (o master / layout) puede usarlo así (sintaxis 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>
Espero eso ayude.
Puede obtener estos datos de RouteData de un ViewContext
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]
En MVC, debe proporcionar a la Vista todos los datos, no permitir que la Vista recopile sus propios datos, por lo que lo que puede hacer es establecer la clase CSS en la acción de su controlador.
ViewData["CssClass"] = "bold";
y seleccione este valor de su ViewData en su Vista
Yo voto por este 2:
string currentActionName = ViewContext.RouteData.GetRequiredString("action");
y
string currentViewName = ((WebFormView)ViewContext.View).ViewPath;
Puede recuperar el nombre físico de la vista actual y la acción que lo activó. Puede ser útil en páginas parciales * .acmx para determinar el contenedor del host.
Extendiendo la respuesta de Dale Ragan , su ejemplo para la reutilización, cree una clase ApplicationController que se derive de Controller y, a su vez, haga que todos sus otros controladores se deriven de esa clase ApplicationController en lugar de Controller.
Ejemplo:
public class MyCustomApplicationController : Controller {}
public class HomeController : MyCustomApplicationController {}
En su nuevo ApplicationController, cree una propiedad llamada ExecutingAction con esta firma:
protected ActionDescriptor ExecutingAction { get; set; }
Y luego, en el método OnActionExecuting (de la respuesta de Dale Ragan), simplemente asigne el ActionDescriptor a esta propiedad y podrá acceder a él cuando lo necesite en cualquiera de sus controladores.
string currentActionName = this.ExecutingAction.ActionName;
Anular esta función en su controlador
protected override void HandleUnknownAction(string actionName)
{ TempData["actionName"] = actionName;
View("urViewName").ExecuteResult(this.ControllerContext);
}