Ответы:
Используйте ViewContext
и посмотрите на RouteData
коллекцию, чтобы извлечь элементы контроллера и действия. Но я думаю, что установка некоторой переменной данных, которая указывает контекст приложения (например, «режим редактирования» или «ошибка»), а не контроллер / действие, уменьшает связь между вашими представлениями и контроллерами.
В RC вы также можете извлечь данные маршрута, например, имя метода действия, например:
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
+ вариации
Чтобы получить текущий идентификатор в представлении:
ViewContext.RouteData.Values["id"].ToString()
Чтобы получить текущий контроллер:
ViewContext.RouteData.Values["controller"].ToString()
ViewContext.RouteData.Values.ContainsKey(<key>)
сначала.
Я знаю, что это более старый вопрос, но я видел его и подумал, что вам может быть интересна альтернативная версия, чем позволить вашему представлению обрабатывать данные, необходимые для его работы.
На мой взгляд, более простым способом было бы переопределить метод OnActionExecuting . Вам передается ActionExecutingContext, который содержит член ActionDescriptor, который вы можете использовать для получения искомой информации, который является 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.
}
Надеюсь это поможет. Если что-нибудь, по крайней мере, это покажет альтернативу для кого-либо еще, что приходит на ваш вопрос.
Я видел разные ответы и придумал помощника класса:
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):
<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>
Надеюсь, поможет.
Вы можете получить эти данные из RouteData ViewContext
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]
В MVC вы должны предоставлять View со всеми данными, а не позволять View собирать свои собственные данные, поэтому вы можете установить класс CSS в действии вашего контроллера.
ViewData["CssClass"] = "bold";
и выберите это значение из ваших ViewData в вашем View
Я голосую за это 2:
string currentActionName = ViewContext.RouteData.GetRequiredString("action");
и
string currentViewName = ((WebFormView)ViewContext.View).ViewPath;
Вы можете получить как физическое имя текущего представления, так и действие, которое его вызвало. Это может быть полезно в частичных * .acmx страницах для определения хост-контейнера.
Расширяя ответ Дейла Рэгана , его пример для повторного использования, создайте класс ApplicationController, который является производным от Controller, и, в свою очередь, все остальные контроллеры наследуются от этого класса ApplicationController, а не Controller.
Пример:
public class MyCustomApplicationController : Controller {}
public class HomeController : MyCustomApplicationController {}
В вашем новом ApplicationController создайте свойство с именем ExecutingAction с этой подписью:
protected ActionDescriptor ExecutingAction { get; set; }
А затем в методе OnActionExecuting (из ответа Дейла Рагана) просто назначьте ActionDescriptor этому свойству, и вы сможете получить к нему доступ, когда вам это понадобится в любом из ваших контроллеров.
string currentActionName = this.ExecutingAction.ActionName;
Переопределите эту функцию в вашем контроллере
protected override void HandleUnknownAction(string actionName)
{ TempData["actionName"] = actionName;
View("urViewName").ExecuteResult(this.ControllerContext);
}