Odpowiedzi:
Użyj ViewContext
i spójrz na RouteData
kolekcję, aby wyodrębnić zarówno kontroler, jak i elementy akcji. Ale myślę, że ustawienie zmiennej danych wskazującej kontekst aplikacji (np. „Editmode” lub „error”) zamiast kontrolera / akcji zmniejsza sprzężenie między twoimi widokami a kontrolerami.
W RC można także wyodrębnić dane trasy, takie jak nazwa metody akcji, jak ta
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
+ odmiany
Aby uzyskać bieżący identyfikator w widoku:
ViewContext.RouteData.Values["id"].ToString()
Aby uzyskać bieżący kontroler:
ViewContext.RouteData.Values["controller"].ToString()
ViewContext.RouteData.Values.ContainsKey(<key>)
pierwszym.
Wiem, że to jest starsze pytanie, ale widziałem je i pomyślałem, że może zainteresuje Cię alternatywna wersja, niż pozwalanie twojemu widokowi obsługiwać pobieranie danych potrzebnych do wykonania zadania.
Moim zdaniem łatwiejszym sposobem byłoby zastąpienie metody OnActionExecuting . Przekazano Ci ActionExecutingContext, który zawiera członka ActionDescriptor, którego możesz użyć do uzyskania poszukiwanych informacji, którym jest ActionName, i możesz także uzyskać dostęp do ControllerDescriptor, który zawiera 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.
}
Mam nadzieję że to pomoże. Jeśli cokolwiek, to przynajmniej pokaże alternatywę dla każdego, kto przyjdzie na twoje pytanie.
Widziałem różne odpowiedzi i wymyśliłem pomocnika klasy:
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;
}
}
}
Tak więc w View (lub master / layout) możesz używać go w ten sposób (składnia 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>
Mam nadzieję, że to pomoże.
Możesz pobrać te dane z RouteData obiektu ViewContext
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]
W MVC powinieneś dostarczyć widokowi wszystkie dane, nie pozwalając widokowi zbierać własnych danych, więc możesz ustawić klasę CSS w akcji kontrolera.
ViewData["CssClass"] = "bold";
i wybierz tę wartość z ViewData w swoim widoku
Głosuję za tym 2:
string currentActionName = ViewContext.RouteData.GetRequiredString("action");
i
string currentViewName = ((WebFormView)ViewContext.View).ViewPath;
Możesz pobrać zarówno nazwę fizyczną bieżącego widoku, jak i akcję, która go uruchomiła. Może być przydatny na częściowych stronach * .acmx do określenia kontenera hosta.
Rozszerzając odpowiedź Dale Ragana , jego przykład do ponownego użycia, stwórz klasę ApplicationController, która wywodzi się z kontrolera, a z kolei wszystkie inne kontrolery wywodzą się z tej klasy ApplicationController, a nie z kontrolera.
Przykład:
public class MyCustomApplicationController : Controller {}
public class HomeController : MyCustomApplicationController {}
Na nowym ApplicationController utwórz właściwość o nazwie ExecutingAction z tym podpisem:
protected ActionDescriptor ExecutingAction { get; set; }
Następnie w metodzie OnActionExecuting (z odpowiedzi Dale'a Ragana) po prostu przypisz ActionDescriptor do tej właściwości, aby uzyskać do niej dostęp w dowolnym momencie na dowolnym kontrolerze.
string currentActionName = this.ExecutingAction.ActionName;
Zastąp tę funkcję w swoim kontrolerze
protected override void HandleUnknownAction(string actionName)
{ TempData["actionName"] = actionName;
View("urViewName").ExecuteResult(this.ControllerContext);
}