Aktuellen Bereichsnamen in Ansicht oder Controller abrufen

126

Wie erhält man den aktuellen Bereichsnamen in der Ansicht oder im Controller?

Gibt es so etwas ViewContext.RouteData.Values["controller"]für Gebiete?

user202448
quelle

Antworten:

217

Ab MVC2 können Sie verwenden ViewContext.RouteData.DataTokens["area"]

artvolk
quelle
22
Wenn nicht in einem Bereich, ViewContext.RouteData.DataTokens ["Bereich"] == null.
user202448
23
... und in MVC5 :)
Stefan
4
Lol .. der Witz ist auf dich @Dante ... um fair zu sein, heißt es ASP.NET Core 1.0statt MVC6.. :-)
Rosdi Kasim
Zu Ihrer Information - herausgefunden, was mit meinem Ajax-POST nicht stimmte, funktionierte nicht ... Bitte überprüfen Sie, ob Ihre Ajax-Anfragen den Bereich in der URL haben ... sie finden ihn möglicherweise noch !!! die Ansicht, aber sie werden den Bereich nicht pflegen ... wenn der URL der Bereich fehlt, wenn die Anfrage gestellt wird.
Seabizkit
43
HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"]
Slava
quelle
3
Dies ist der beste, universelle Weg, um die Bereichsinformationen abzurufen, wenn Sie sich nicht in einer Ansicht oder einem Controller befinden. Danke, dass du das gepostet hast!
Bdrelling
19

Sie können es vom Controller erhalten, indem Sie:

ControllerContext.RouteData.DataTokens["area"]
Matt Penner
quelle
@ user202338 Bereiche wurden in MVC2 eingeführt, daher würde ich dies vermuten, aber ich bin nicht sicher, ob sie die Art und Weise geändert haben, in der sie die DataTokens-Sammlung füllen. Ich sehe Beiträge wie diesen: Link , der über die Verwendung in MVC2 spricht.
Matt Penner
10

In ASP.NET Core 1.0 befindet sich der Wert in

ViewContext.RouteData.Values ​​["area"];

zerox981
quelle
Bist du sicher? Soweit ich mich erinnern kann, hat es funktioniert, als wir unsere App auf ASP.NET Core 2.0 ausgeführt haben und funktioniert jetzt noch in ASP.NET Core 2.1 (vor wenigen Augenblicken getestet).
zerox981
Sie haben Recht, arbeiten nicht nur für Rasiermesserseiten (es gibt keinen ViewContext - pageModel.RouteData.Values.TryGetValue("area", out object area)sollte stattdessen verwendet werden)
Roman Pokrovskij
9

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>
christesene
quelle
Aus irgendeinem Grund kann ich den areaToken nicht in der finden Values, musste aber in der DataTokens... keine Ahnung warum.
Syska
8

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 RouteDataist auf beiden verfügbar ControllerContextund ViewContextes 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.DataTokensnull ist, da dies immer intern initialisiert wird.

Ben Foster
quelle
3

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.

Levi
quelle
1
Gibt es eine solche Methode für Controller? Ich hasse es, String-Literale in einer Sammlung zu verwenden.
Erick T
für Controller-Verwendung this.GetName()und für die aktuelle Methode verwendenMethodBase.GetCurrentMethod().Name
Nerdroid
3

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.

gcoleman0828
quelle
2

So rufen Sie den Bereichsnamen in der Ansicht in ASP.NET Core MVC 2.1 ab:

@Context.GetRouteData().Values["area"]
Netstep
quelle
2

Abrufen des Bereichsnamens in View (.NET Core 2.2):

ViewContext?.ActionDescriptor?.RouteValues["area"]
SZL
quelle
0

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.

Joao Nunes da Silva
quelle
0

Ich weiß nicht warum, aber akzeptierte Antwort funktioniert nicht. Es gibt null zurück mit zB (vielleicht über mvc, ich benutze .net Core)

http: // localhost: 5000 / Admin / CustomerGroup

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";
Fthopkins
quelle