关于c#:如何在ASP.NET MVC视图中返回当前操作?

How can I return the current action in an ASP.NET MVC view?

我想在我的母版页中设置一个CSS类,这取决于当前的控制器和操作。 我可以通过ViewContext.Controller.GetType().Name到达当前控制器,但是如何获取当前操作(例如IndexShow等)?


在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"]


使用ViewContext并查看RouteData集合以提取控制器和操作元素。但我认为设置一些指示应用程序上下文的数据变量(例如"editmode"或"error")而不是控制器/操作会减少视图和控制器之间的耦合。


要获取视图上的当前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;