C# 如何在 ASP.NET MVC 视图中返回当前操作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/362514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I return the current action in an ASP.NET MVC view?
提问by buggs
I wanted to set a CSS class in my master page, which depends on the current controller and action. I can get to the current controller via ViewContext.Controller.GetType().Name
, but how do I get the current action (e.g. Index
, Show
etc.)?
我想在我的母版页中设置一个 CSS 类,这取决于当前的控制器和操作。我可以通过 访问当前控制器ViewContext.Controller.GetType().Name
,但是如何获得当前操作(例如Index
,Show
等)?
采纳答案by tvanfosson
Use the ViewContext
and look at the RouteData
collection to extract both the controller and action elements. But I think setting some data variable that indicates the application context (e.g., "editmode" or "error") rather than controller/action reduces the coupling between your views and controllers.
使用ViewContext
和 查看RouteData
集合来提取控制器和操作元素。但是我认为设置一些指示应用程序上下文(例如,“editmode”或“error”)而不是控制器/动作的数据变量可以减少视图和控制器之间的耦合。
回答by terjetyl
In MVC you should provide the View with all data, not let the View collect its own data so what you can do is to set the CSS class in your controller action.
在 MVC 中,您应该为 View 提供所有数据,而不是让 View 收集自己的数据,因此您可以做的是在控制器操作中设置 CSS 类。
ViewData["CssClass"] = "bold";
and pick out this value from your ViewData in your View
并从您的 View 中的 ViewData 中挑选出这个值
回答by tsquillario
To get the current Id on a View:
要获取视图上的当前 ID:
ViewContext.RouteData.Values["id"].ToString()
To get the current controller:
获取当前控制器:
ViewContext.RouteData.Values["controller"].ToString()
回答by Christian Dalager
In the RC you can also extract route data like the action method name like this
在 RC 中,您还可以像这样提取路线数据,例如动作方法名称
ViewContext.Controller.ValueProvider["action"].RawValue
ViewContext.Controller.ValueProvider["controller"].RawValue
ViewContext.Controller.ValueProvider["id"].RawValue
Update for MVC 3
MVC 3 更新
ViewContext.Controller.ValueProvider.GetValue("action").RawValue
ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
ViewContext.Controller.ValueProvider.GetValue("id").RawValue
Update for MVC 4
MVC 4 更新
ViewContext.Controller.RouteData.Values["action"]
ViewContext.Controller.RouteData.Values["controller"]
ViewContext.Controller.RouteData.Values["id"]
Update for MVC 4.5
MVC 4.5 更新
ViewContext.RouteData.Values["action"]
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["id"]
回答by Dale Ragan
I know this is an older question, but I saw it and I thought you might be interested in an alternative version than letting your view handle retrieving the data it needs to do it's job.
我知道这是一个较旧的问题,但我看到了它,我认为您可能对替代版本感兴趣,而不是让您的视图处理检索它完成工作所需的数据。
An easier way in my opinion would be to override the OnActionExecutingmethod. You are passed the ActionExecutingContextthat contains the ActionDescriptormember which you can use to obtain the information you are looking for, which is the ActionName and you can also reach the ControllerDescriptor and it contains the ControllerName.
在我看来,更简单的方法是覆盖OnActionExecuting方法。您将获得包含ActionDescriptor成员的ActionExecutingContext,您可以使用该成员获取您要查找的信息,即 ActionName,您还可以访问 ControllerDescriptor,其中包含 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.
}
Hope this helps. If anything, at least it will show an alternative for anybody else that comes by your question.
希望这可以帮助。如果有的话,至少它会为您提出问题的任何其他人提供替代方案。
回答by Dale Ragan
I vote for this 2:
我投这2票:
string currentActionName = ViewContext.RouteData.GetRequiredString("action");
and
和
string currentViewName = ((WebFormView)ViewContext.View).ViewPath;
You can retrive both physical name of current view and action that triggered it. It can be usefull in partial *.acmx pages to determine host container.
您可以检索当前视图的物理名称和触发它的操作。在部分 *.acmx 页面中确定主机容器很有用。
回答by RunnerRick
Extending Dale Ragan's answer, his example for reuse, create an ApplicationController class which derives from Controller, and in turn have all your other controllers derive from that ApplicationController class rather than Controller.
扩展Dale Ragan 的答案,他的重用示例,创建一个从 Controller 派生的 ApplicationController 类,然后让所有其他控制器从该 ApplicationController 类而不是 Controller 派生。
Example:
例子:
public class MyCustomApplicationController : Controller {}
public class HomeController : MyCustomApplicationController {}
On your new ApplicationController create a property named ExecutingAction with this signature:
在您的新 ApplicationController 上,使用此签名创建一个名为 ExecutingAction 的属性:
protected ActionDescriptor ExecutingAction { get; set; }
And then in the OnActionExecuting method (from Dale Ragan's answer), simply assign the ActionDescriptor to this property and you can access it whenever you need it in any of your controllers.
然后在 OnActionExecuting 方法中(来自 Dale Ragan 的回答),只需将 ActionDescriptor 分配给此属性,您就可以在任何控制器中随时访问它。
string currentActionName = this.ExecutingAction.ActionName;
回答by Michael Vashchinsky
I saw different answers and came up with a class helper:
我看到了不同的答案,并想出了一个班级助手:
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;
}
}
}
So in View (or master/layout) you can use it like so (Razor syntax):
因此,在视图(或主/布局)中,您可以像这样使用它(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>
Hope it helps.
希望能帮助到你。
回答by Viacheslav Smityukh
You can get these data from RouteData of a ViewContext
您可以从 ViewContext 的 RouteData 获取这些数据
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]
回答by kiewic
I am using ASP.NET MVC 4, and this what worked for me:
我正在使用 ASP.NET MVC 4,这对我有用:
ControllerContext.Controller.ValueProvider.GetValue("controller").RawValue
ControllerContext.Controller.ValueProvider.GetValue("action").RawValue