134 votes

Obtenir le nom de la zone actuelle dans la vue ou le contrôleur

Comment obtenir le nom de la zone actuelle dans la vue ou le contrôleur ?

Y a-t-il quelque chose comme ViewContext.RouteData.Values["controller"] pour les zones ?

233voto

artvolk Points 3208

À partir de MVC2, vous pouvez utiliser ViewContext.RouteData.DataTokens["area"]

22 votes

Si elle ne se trouve pas dans une zone, ViewContext.RouteData.DataTokens["area"] == null.

4 votes

Lol... la blague est sur vous @Dante ... bien pour être juste elle est appelée ASP.NET Core 1.0 au lieu de MVC6 .. :-)

0 votes

Pour info - j'ai découvert ce qui n'allait pas avec mes POST ajax qui ne fonctionnaient pas... veuillez vérifier que vos requêtes ajax ont la zone dans l'URL... elles peuvent toujours trouver ! !! la vue, mais elles ne maintiendront pas la zone... si l'url manque la zone quand la requête est faite.

49voto

Slava Points 590
HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"]

3 votes

C'est le meilleur, universel pour obtenir les informations sur la zone, si vous n'êtes pas dans une vue ou un contrôleur. Merci d'avoir publié cet article !

20voto

Matt Penner Points 418

Vous pouvez l'obtenir à partir du contrôleur en utilisant :

ControllerContext.RouteData.DataTokens["area"]

0 votes

@user202338 Les zones ont été introduites dans MVC2, je le soupçonne donc, mais je ne suis pas sûr qu'elles aient changé la façon dont elles alimentent la collection DataTokens. Je vois des messages comme celui-ci : enlace qui parlent de son utilisation dans MVC2.

9voto

christesene Points 51

Je viens d'écrire un b entrée de journal à ce sujet Vous pouvez consulter ce site pour plus de détails, mais ma réponse a été de créer une méthode d'extension, illustrée ci-dessous.

L'élément clé est que vous tirez la zone MVC des .DataTokens et le contrôleur/action des .Values de la 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;
    }

Vous pouvez alors l'implémenter comme suit :

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

0 votes

Pour une raison quelconque, je n'arrive pas à trouver le area dans le Values mais il fallait regarder dans le DataTokens ... aucune idée pourquoi.

8voto

Ben Foster Points 11699

J'ai créé une méthode d'extension pour RouteData qui renvoie le nom de la zone actuelle.

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

    return null;
}

Depuis RouteData est disponible à la fois sur ControllerContext y ViewContext il est possible d'y accéder dans votre contrôleur et vos vues.

Il est également très facile à tester :

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

Il n'est pas nécessaire de vérifier si RouteData.DataTokens est nulle, car elle est toujours initialisée en interne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X