Ottieni nome area corrente in Visualizza o Controller


126

Come si ottiene il nome dell'area corrente nella vista o nel controller?

C'è qualcosa di simile ViewContext.RouteData.Values["controller"]per le aree?

Risposte:


217

Da MVC2 in poi puoi usare ViewContext.RouteData.DataTokens["area"]


22
Se non in un'area, ViewContext.RouteData.DataTokens ["area"] == null.
user202448

23
... e in MVC5 :)
Stefan,

4
Lol .. lo scherzo è su di te @Dante ... beh per essere onesti si chiama ASP.NET Core 1.0invece di MVC6.. :-)
Rosdi Kasim

Cordiali saluti - ho scoperto che cosa non andava nel mio ajax POST non funzionava ... controlla che le tue richieste ajax abbiano l'area nell'URL ... potrebbero ancora trovare !!! la vista, ma non manterranno l'area ... se all'URL manca l'area al momento della richiesta.
Seabizkit,

43
HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"]

3
Questo è il modo migliore e universale per ottenere le informazioni sull'area, se non ti trovi in ​​una vista o controller. Grazie per aver pubblicato questo!
bdrelling

19

Puoi ottenerlo dal controller usando:

ControllerContext.RouteData.DataTokens["area"]

@ user202338 Le aree sono state introdotte in MVC2, quindi lo sospetto, ma non sono sicuro che abbiano cambiato il modo in cui popolano la raccolta DataTokens. Vedo post come questo: link che parlano dell'utilizzo in MVC2.
Matt Penner,

10

In ASP.NET Core 1.0 il valore si trova in

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


Sei sicuro? Per quanto posso ricordare, ha funzionato quando abbiamo eseguito la nostra app su ASP.NET Core 2.0 e funziona ancora ora su ASP.NET Core 2.1 (testato qualche tempo fa).
zerox981,

Hai ragione, non funziona solo per Razor Pages (non ci sono ViewContext - pageModel.RouteData.Values.TryGetValue("area", out object area)dovrebbe essere usato invece)
Roman Pokrovskij

9

Ho appena scritto una voce di registro su questo , puoi visitarlo per maggiori dettagli, ma la mia risposta è stata quella di creare un metodo di estensione, mostrato di seguito.

Il kicker chiave è stato estrarre l'Area MVC da .DataTokens e il controller / azione dai .Values ​​di RouteData.

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;
    }

Quindi puoi implementarlo come di seguito:

<ul id="menu">
@Html.TopMenuLink("Dashboard", "Home", "Index", "", "Click here for the dashboard.")
@Html.TopMenuLink("Courses", "Home", "Index", "Courses", "List of our Courses.")
</ul>

Per qualche motivo non riesco a trovare il areatoken nel Valuesma avevo bisogno di guardare nel DataTokens... non ho idea del perché.
Syska,

8

Ho creato un metodo di estensione per RouteDataquello restituisce il nome dell'area corrente.

public static string GetAreaName(this RouteData routeData)
{
    object area;
    if (routeData.DataTokens.TryGetValue("area", out area))
    {
        return area as string;
    }

    return null;
}

Poiché RouteDataè disponibile su entrambi ControllerContexte ViewContextè possibile accedervi dal controller e dalle visualizzazioni.

È anche molto facile testare:

[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();
    }
}

Non è necessario verificare se RouteData.DataTokensè null poiché è sempre inizializzato internamente.


3

MVC Futures ha un metodo AreaHelpers.GetAreaName (). Tuttavia, prestare attenzione se si utilizza questo metodo. L'uso dell'area corrente per prendere decisioni di runtime sull'applicazione potrebbe portare a codici difficili da eseguire il debug o non sicuri.


1
Esiste un metodo simile per i controller? Odio usare letterali stringa in una raccolta.
Erick T,

per l'uso del controller this.GetName()e per l'uso del Metodo correnteMethodBase.GetCurrentMethod().Name
Nerdroid

3

So che questo è vecchio, ma anche, quando in un filtro come ActionFilter, il contesto non fornisce facilmente le informazioni sull'area.

Si può trovare nel seguente codice:

var routeData = filterContext.RequestContext.RouteData;

if (routeData.DataTokens["area"] != null)
    area = routeData.DataTokens["area"].ToString();

Quindi il filterContext viene passato sull'override e il RouteData corretto viene trovato in RequestContext. C'è un RoutData a livello Base, ma i DataTokens NON hanno l'area nel suo dizionario.


2

Per ottenere il nome dell'area nella vista, in ASP.NET Core MVC 2.1:

@Context.GetRouteData().Values["area"]

2

Ottieni il nome dell'area in Visualizza (.NET Core 2.2):

ViewContext?.ActionDescriptor?.RouteValues["area"]

0

So che questo è un post molto vecchio ma possiamo usare la proprietà Values ​​esattamente allo stesso modo dei DataTokens

Url.RequestContext.RouteData.Values ​​["action"] ha funzionato per me.


0

Non so perché ma la risposta accettata non funziona. Restituisce null con es. (Forse su mvc, io uso .net core)

http: // localhost: 5000 / admin / CustomerGroup

Eseguo sempre il debug della variabile e recupero i dati da essa.

Prova questo. Per me funziona

var area = ViewContext.RouteData.Values["area"]

Esempio logico dettagliato

Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.