How can I return the current action in an ASP.NET MVC view?
我想在我的母版页中设置一个CSS类,这取决于当前的控制器和操作。 我可以通过
在RC中,您还可以像这样提取路径数据,如操作方法名称
1 2 3 | ViewContext.Controller.ValueProvider["action"].RawValue ViewContext.Controller.ValueProvider["controller"].RawValue ViewContext.Controller.ValueProvider["id"].RawValue |
MVC 3的更新
1 2 3 | ViewContext.Controller.ValueProvider.GetValue("action").RawValue ViewContext.Controller.ValueProvider.GetValue("controller").RawValue ViewContext.Controller.ValueProvider.GetValue("id").RawValue |
MVC 4更新
1 2 3 | ViewContext.Controller.RouteData.Values["action"] ViewContext.Controller.RouteData.Values["controller"] ViewContext.Controller.RouteData.Values["id"] |
MVC 4.5的更新
1 2 3 | ViewContext.RouteData.Values["action"] ViewContext.RouteData.Values["controller"] ViewContext.RouteData.Values["id"] |
使用
要获取视图上的当前ID:
1 | ViewContext.RouteData.Values["id"].ToString() |
要获得当前的控制器:
1 | ViewContext.RouteData.Values["controller"].ToString() |
我知道这是一个较旧的问题,但是我看到它并且我认为您可能对替代版本感兴趣,而不是让您的视图处理检索它所需的数据来完成它的工作。
在我看来,更简单的方法是覆盖OnActionExecuting方法。您将传递包含ActionDescriptor成员的ActionExecutingContext,您可以使用该成员获取您要查找的信息,即ActionName,您还可以访问ControllerDescriptor并且它包含ControllerName。
1 2 3 4 5 6 7 8 | 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. } |
希望这可以帮助。如果有的话,至少它会为你的问题所带来的任何其他人展示另一种选择。
我看到了不同的答案,并想出了一个班助手:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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; } } } |
所以在View(或master / layout)中你可以这样使用它(Razor语法):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <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> |
希望能帮助到你。
您可以从ViewContext的RouteData获取这些数据
1 2 | ViewContext.RouteData.Values["controller"] ViewContext.RouteData.Values["action"] |
在MVC中,您应该为View提供所有数据,而不是让View收集自己的数据,因此您可以在控制器操作中设置CSS类。
1 | ViewData["CssClass"] ="bold"; |
并从View中的ViewData中选择此值
我投票支持这个2:
1 | string currentActionName = ViewContext.RouteData.GetRequiredString("action"); |
和
1 | string currentViewName = ((WebFormView)ViewContext.View).ViewPath; |
您可以检索当前视图的物理名称和触发它的操作。它可以在部分* .acmx页面中用于确定主机容器。
我正在使用ASP.NET MVC 4,这对我有用:
1 2 | ControllerContext.Controller.ValueProvider.GetValue("controller").RawValue ControllerContext.Controller.ValueProvider.GetValue("action").RawValue |
在控制器中覆盖此功能
1 2 3 4 | protected override void HandleUnknownAction(string actionName) { TempData["actionName"] = actionName; View("urViewName").ExecuteResult(this.ControllerContext); } |
扩展Dale Ragan的答案,他的重用示例,创建一个派生自Controller的ApplicationController类,然后让所有其他控制器派生自ApplicationController类而不是Controller。
例:
1 2 3 | public class MyCustomApplicationController : Controller {} public class HomeController : MyCustomApplicationController {} |
在新的ApplicationController上,使用以下签名创建名为ExecutingAction的属性:
1 | protected ActionDescriptor ExecutingAction { get; set; } |
然后在OnActionExecuting方法中(来自Dale Ragan的答案),只需将ActionDescriptor分配给此属性,您就可以在任何控制器中随时访问它。
1 | string currentActionName = this.ExecutingAction.ActionName; |