web-dev-qa-db-fra.com

ASP.NET MVC - Obtenir le nom de la zone actuelle dans la vue ou le contrôleur

Comment obtenez-vous le nom actuel de la zone dans la vue ou le contrôleur?

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

119
user202448

Dans MVC 2, vous pouvez utiliser ViewContext.RouteData.DataTokens["area"]

206
artvolk
HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"]
38
Slava

Vous pouvez l'obtenir auprès du contrôleur en utilisant:

ControllerContext.RouteData.DataTokens["area"]
18
Matt Penner

Je viens d'écrire une entrée de b log à ce sujet , vous pouvez la visiter pour plus de détails, mais ma réponse était de créer une méthode d'extension, illustrée ci-dessous.

Le kicker clé était que vous extrayez la zone MVC de .DataTokens et le contrôleur/action des valeurs .Values ​​de 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;
    }

Ensuite, vous pouvez le mettre en œuvre comme ci-dessous:

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

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

Puisque RouteData est disponible à la fois sur ControllerContext et ViewContext, vous pouvez y accéder dans votre contrôleur et vos vues.

Il est également très facile de 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 null car celui-ci est toujours initialisé en interne.

8
Ben Foster

Dans ASP.NET Core 1.0, la valeur se trouve dans

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

8
zerox981

MVC Futures a une méthode AreaHelpers.GetAreaName (). Cependant, soyez prudent si vous utilisez cette méthode. L'utilisation de la zone actuelle pour prendre des décisions d'exécution concernant votre application peut générer un code difficile à déboguer ou peu sécurisé.

3
Levi

Je sais que c'est vieux, mais aussi, quand dans un filtre comme ActionFilter, le contexte ne vous fournit pas facilement les informations de zone.

On peut le trouver dans le code suivant:

var routeData = filterContext.RequestContext.RouteData;

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

Donc, le filterContext est transmis à la substitution et le bon RouteData se trouve sous le RequestContext. Il y a un RoutData au niveau de la base, mais le DataTokens N'A PAS la zone dans son dictionnaire.

3
gcoleman0828

Obtenir le nom de la zone dans View (.NET Core 2.2):

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

Je sais que c'est un très vieux billet mais nous pouvons utiliser la propriété Values ​​exactement de la même manière que le DataTokens 

Url.RequestContext.RouteData.Values ​​["action"] a fonctionné pour moi.

0
Joao Nunes da Silva

Pour obtenir le nom de la zone dans la vue, dans ASP.NET Core MVC 2.1:

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