Wie erhält man den aktuellen Bereichsnamen in der Ansicht oder im Controller?
Gibt es so etwas ViewContext.RouteData.Values["controller"]
für Gebiete?
Wie erhält man den aktuellen Bereichsnamen in der Ansicht oder im Controller?
Gibt es so etwas ViewContext.RouteData.Values["controller"]
für Gebiete?
Antworten:
Ab MVC2 können Sie verwenden ViewContext.RouteData.DataTokens["area"]
ASP.NET Core 1.0
statt MVC6
.. :-)
Sie können es vom Controller erhalten, indem Sie:
ControllerContext.RouteData.DataTokens["area"]
In ASP.NET Core 1.0 befindet sich der Wert in
ViewContext.RouteData.Values ["area"];
pageModel.RouteData.Values.TryGetValue("area", out object area)
sollte stattdessen verwendet werden)
Ich habe gerade einen Protokolleintrag darüber geschrieben . Sie können ihn für weitere Details besuchen, aber meine Antwort war, eine Erweiterungsmethode zu erstellen (siehe unten).
Der entscheidende Kicker war, dass Sie den MVC-Bereich aus den .DataTokens und den Controller / die Aktion aus den .Values der RouteData ziehen.
public static MvcHtmlString TopMenuLink(this HtmlHelper htmlHelper, string linkText, string controller, string action, string area, string anchorTitle)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var url = urlHelper.Action(action, controller, new { @area = area });
var anchor = new TagBuilder("a");
anchor.InnerHtml = HttpUtility.HtmlEncode(linkText);
anchor.MergeAttribute("href", url);
anchor.Attributes.Add("title", anchorTitle);
var listItem = new TagBuilder("li");
listItem.InnerHtml = anchor.ToString(TagRenderMode.Normal);
if (CheckForActiveItem(htmlHelper, controller, action, area))
listItem.GenerateId("menu_active");
return MvcHtmlString.Create(listItem.ToString(TagRenderMode.Normal));
}
private static bool CheckForActiveItem(HtmlHelper htmlHelper, string controller, string action, string area)
{
if (!CheckIfTokenMatches(htmlHelper, area, "area"))
return false;
if (!CheckIfValueMatches(htmlHelper, controller, "controller"))
return false;
return CheckIfValueMatches(htmlHelper, action, "action");
}
private static bool CheckIfValueMatches(HtmlHelper htmlHelper, string item, string dataToken)
{
var routeData = (string)htmlHelper.ViewContext.RouteData.Values[dataToken];
if (routeData == null) return string.IsNullOrEmpty(item);
return routeData == item;
}
private static bool CheckIfTokenMatches(HtmlHelper htmlHelper, string item, string dataToken)
{
var routeData = (string)htmlHelper.ViewContext.RouteData.DataTokens[dataToken];
if (dataToken == "action" && item == "Index" && string.IsNullOrEmpty(routeData))
return true;
if (dataToken == "controller" && item == "Home" && string.IsNullOrEmpty(routeData))
return true;
if (routeData == null) return string.IsNullOrEmpty(item);
return routeData == item;
}
Dann können Sie es wie folgt implementieren:
<ul id="menu">
@Html.TopMenuLink("Dashboard", "Home", "Index", "", "Click here for the dashboard.")
@Html.TopMenuLink("Courses", "Home", "Index", "Courses", "List of our Courses.")
</ul>
area
Token nicht in der finden Values
, musste aber in der DataTokens
... keine Ahnung warum.
Ich habe eine Erweiterungsmethode erstellt RouteData
, die den aktuellen Bereichsnamen zurückgibt.
public static string GetAreaName(this RouteData routeData)
{
object area;
if (routeData.DataTokens.TryGetValue("area", out area))
{
return area as string;
}
return null;
}
Da RouteData
ist auf beiden verfügbar ControllerContext
und ViewContext
es kann in Ihrem Controller und Ansichten zugegriffen werden.
Es ist auch sehr einfach zu testen:
[TestFixture]
public class RouteDataExtensionsTests
{
[Test]
public void GetAreaName_should_return_area_name()
{
var routeData = new RouteData();
routeData.DataTokens.Add("area", "Admin");
routeData.GetAreaName().ShouldEqual("Admin");
}
[Test]
public void GetAreaName_should_return_null_when_not_set()
{
var routeData = new RouteData();
routeData.GetAreaName().ShouldBeNull();
}
}
Es muss nicht überprüft werden, ob RouteData.DataTokens
null ist, da dies immer intern initialisiert wird.
MVC Futures verfügt über eine AreaHelpers.GetAreaName () -Methode. Seien Sie jedoch vorsichtig, wenn Sie diese Methode verwenden. Die Verwendung des aktuellen Bereichs, um Laufzeitentscheidungen über Ihre Anwendung zu treffen, kann zu schwer zu debuggendem oder unsicherem Code führen.
this.GetName()
und für die aktuelle Methode verwendenMethodBase.GetCurrentMethod().Name
Ich weiß, dass dies alt ist, aber auch in einem Filter wie ActionFilter liefert Ihnen der Kontext nicht einfach die Bereichsinformationen.
Es kann im folgenden Code gefunden werden:
var routeData = filterContext.RequestContext.RouteData;
if (routeData.DataTokens["area"] != null)
area = routeData.DataTokens["area"].ToString();
Der filterContext wird also beim Überschreiben übergeben und die richtigen RouteData werden unter dem RequestContext gefunden. Es gibt RoutData auf der Basisebene, aber die DataTokens haben NICHT den Bereich in ihrem Wörterbuch.
Ich weiß, dass dies ein sehr sehr alter Beitrag ist, aber wir können die Values-Eigenschaft genauso verwenden wie die DataTokens
Url.RequestContext.RouteData.Values ["Aktion"] hat bei mir funktioniert.
Ich weiß nicht warum, aber akzeptierte Antwort funktioniert nicht. Es gibt null zurück mit zB (vielleicht über mvc, ich benutze .net Core)
Ich debugge immer die Variable und rufe Daten darin ab.
Versuche dies. Für mich geht das
var area = ViewContext.RouteData.Values["area"]
Detailliertes logisches Beispiel
Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";