2010-04-27 5 views

Répondre

194

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

+22

Si ce n'est pas dans une zone, ViewContext.RouteData.DataTokens [" area "] == null. – user202448

+14

mêmes travaux dans MVC 3 –

+21

fonctionne également dans MVC4. – CallMeLaNN

2

MVC Futures possède une méthode AreaHelpers.GetAreaName(). Cependant, soyez prudent si vous utilisez cette méthode. L'utilisation de la zone en cours pour prendre des décisions d'exécution à propos de votre application peut entraîner un code difficile à déboguer ou non sécurisé.

+1

Existe-t-il une méthode semblable à celle des contrôleurs?Je déteste utiliser des littéraux de chaîne dans une collection. –

+0

pour l'utilisation du contrôleur 'this.GetName()' et pour la méthode actuelle, utilisez 'MethodBase.GetCurrentMethod(). Name' – Moes

16

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

ControllerContext.RouteData.DataTokens["area"] 
+0

Est-ce nouveau pour MVC3 ou fonctionne-t-il avec MVC2? – user202448

+0

@ user202338 Les zones ont été introduites dans MVC2 donc je le soupçonne, mais je ne suis pas sûr qu'elles aient changé la manière dont elles peuplent la collection DataTokens. Je vois des messages comme celui-ci: [link] (http://forums.asp.net/t/1549680.aspx/1) qui parle de l'utiliser dans MVC2. –

7

Je viens d'écrire ab log entry about this, vous pouvez visiter pour plus de détails, mais ma réponse était de créer une méthode d'extension, illustrée ci-dessous.

Le déclencheur de clé était que vous tirez la zone MVC à partir des .DataTokens et du contrôleur/action à partir 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 la 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> 
+0

Pour une raison quelconque, je ne peux pas trouver le jeton 'area' dans le' Values', mais je devais regarder dans le 'DataTokens' ... aucune idée pourquoi. – Syska

3

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

Il se trouve dans le code suivant:

var routeData = filterContext.RequestContext.RouteData; 

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

Ainsi, le filterContext est passé dans le remplacement et la bonne RouteData se trouve sous le RequestContext. Il y a une RoutData au niveau de la base, mais les DataTokens n'ont PAS la zone dans le dictionnaire.

6

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

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 sur ControllerContext et ViewContext il peut être consulté dans votre contrôleur et des 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'y a pas besoin de vérifier si RouteData.DataTokens est nul puisque ce toujours initialisé en interne.

30
HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"] 
+2

C'est le meilleur, * universel * pour obtenir les informations de zone, si vous n'êtes pas dans une vue ou un contrôleur. Merci de l'avoir posté! – bdrelling

0

Je sais que c'est un poste très très vieux, mais nous pouvons utiliser les valeurs de la propriété de la même manière que les DataTokens

Url.RequestContext.RouteData.Values ​​[ « action »] ont travaillé pour moi.

3

Dans ASP.NET 1.0 la valeur de base se trouve dans

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

Questions connexes