Antworten:
Verwenden Sie die ViewContextund sehen Sie sich die RouteDataSammlung an, um sowohl die Controller- als auch die Aktionselemente zu extrahieren. Ich denke jedoch, dass das Festlegen einer Datenvariablen, die den Anwendungskontext angibt (z. B. "Bearbeitungsmodus" oder "Fehler"), anstelle von Controller / Aktion, die Kopplung zwischen Ihren Ansichten und Controllern verringert.
Im RC können Sie auch Routendaten wie den Namen der Aktionsmethode wie folgt extrahieren
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+ Variationen
So erhalten Sie die aktuelle ID in einer Ansicht:
ViewContext.RouteData.Values["id"].ToString()
So erhalten Sie den aktuellen Controller:
ViewContext.RouteData.Values["controller"].ToString()
ViewContext.RouteData.Values.ContainsKey(<key>)zuerst mit.
Ich weiß, dass dies eine ältere Frage ist, aber ich habe sie gesehen und dachte, Sie könnten an einer alternativen Version interessiert sein, als Ihre Ansicht die Daten abrufen zu lassen, die sie für ihre Arbeit benötigt.
Meiner Meinung nach wäre es einfacher, die OnActionExecuting- Methode zu überschreiben . Sie erhalten den ActionExecutingContext , der das ActionDescriptor- Mitglied enthält, mit dem Sie die gesuchten Informationen abrufen können. Dies ist der ActionName. Sie können auch den ControllerDescriptor erreichen und er enthält den 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.
}
Hoffe das hilft. Wenn überhaupt, wird es zumindest eine Alternative für alle anderen zeigen, die von Ihrer Frage kommen.
Ich sah verschiedene Antworten und fand einen Klassenhelfer:
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;
}
}
}
In View (oder Master / Layout) können Sie es also wie folgt verwenden (Razor-Syntax):
<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>
Ich hoffe es hilft.
Sie können diese Daten aus RouteData eines ViewContext abrufen
ViewContext.RouteData.Values["controller"]
ViewContext.RouteData.Values["action"]
In MVC sollten Sie der Ansicht alle Daten zur Verfügung stellen und nicht zulassen, dass die Ansicht ihre eigenen Daten sammelt. Sie können also die CSS-Klasse in Ihrer Controller-Aktion festlegen.
ViewData["CssClass"] = "bold";
und wählen Sie diesen Wert aus Ihren ViewData in Ihrer Ansicht aus
Ich stimme für diese 2:
string currentActionName = ViewContext.RouteData.GetRequiredString("action");
und
string currentViewName = ((WebFormView)ViewContext.View).ViewPath;
Sie können sowohl den physischen Namen der aktuellen Ansicht als auch die Aktion abrufen, die sie ausgelöst hat. Es kann in partiellen * .acmx-Seiten nützlich sein, den Host-Container zu bestimmen.
Erweiterung der Antwort von Dale Ragan , sein Beispiel für die Wiederverwendung, erweitern, erstellen Sie eine ApplicationController-Klasse, die von Controller abgeleitet ist, und lassen Sie alle Ihre anderen Controller von dieser ApplicationController-Klasse und nicht von Controller ableiten.
Beispiel:
public class MyCustomApplicationController : Controller {}
public class HomeController : MyCustomApplicationController {}
Erstellen Sie auf Ihrem neuen ApplicationController eine Eigenschaft namens ExecutingAction mit dieser Signatur:
protected ActionDescriptor ExecutingAction { get; set; }
Weisen Sie dann in der OnActionExecuting-Methode (aus der Antwort von Dale Ragan) dieser Eigenschaft einfach den ActionDescriptor zu, und Sie können jederzeit darauf zugreifen, wenn Sie ihn in einem Ihrer Controller benötigen.
string currentActionName = this.ExecutingAction.ActionName;
Überschreiben Sie diese Funktion in Ihrem Controller
protected override void HandleUnknownAction(string actionName)
{ TempData["actionName"] = actionName;
View("urViewName").ExecuteResult(this.ControllerContext);
}