Obtener el nombre del área actual en la vista o el controlador


126

¿Cómo se obtiene el nombre del área actual en la vista o controlador?

¿Hay algo parecido ViewContext.RouteData.Values["controller"]a las áreas?

Respuestas:


217

Desde MVC2 en adelante puedes usar ViewContext.RouteData.DataTokens["area"]


22
Si no está en un área, ViewContext.RouteData.DataTokens ["area"] == null.
user202448

23
... y en MVC5 :)
Stefan

44
Lol ... la broma está en ti @Dante ... bueno, para ser justos, se llama en ASP.NET Core 1.0lugar de MVC6... :-)
Rosdi Kasim

FYI - descubrí que lo que estaba mal con mi ajax POST no funcionaba ... por favor verifique que sus solicitudes de ajax tengan el área en la URL ... ¡aún pueden encontrarlas! la vista, pero no mantendrán el área ... si a la url le falta el área cuando se realiza la solicitud.
Seabizkit

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

3
Esta es la mejor forma universal de obtener la información del área, si no está dentro de una vista o controlador. ¡Gracias por publicar esto!
bdrelling

19

Puede obtenerlo del controlador usando:

ControllerContext.RouteData.DataTokens["area"]

@ user202338 Las áreas se introdujeron en MVC2, por lo que sospecho que sí, pero no estoy seguro de si han cambiado la forma en que pueblan la colección DataTokens. Veo publicaciones como esta: enlaces que hablan sobre su uso en MVC2.
Matt Penner

10

En ASP.NET Core 1.0, el valor se encuentra en

ViewContext.RouteData.Values ​​["área"];


¿Estás seguro? Hasta donde puedo recordar, funcionó cuando ejecutamos nuestra aplicación en ASP.NET Core 2.0 y todavía funciona ahora en ASP.NET Core 2.1 (probado hace unos momentos).
zerox981

Tienes razón, no solo trabajas para Razor Pages (no hay ViewContext, pageModel.RouteData.Values.TryGetValue("area", out object area)debería usarse en su lugar)
Roman Pokrovskij

9

Acabo de escribir una entrada de registro ab sobre esto , puede visitarla para obtener más detalles, pero mi respuesta fue crear un Método de extensión, que se muestra a continuación.

El factor clave fue que extrajo el Área MVC de .DataTokens y el controlador / acción de .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;
    }

Luego puede implementarlo de la siguiente manera:

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

Por alguna razón, no puedo encontrar el areatoken en el, Valuespero necesitaba buscar en el DataTokens... no tengo idea de por qué.
Syska

8

Creé un método de extensión para RouteDataque devuelva el nombre del área actual.

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

    return null;
}

Dado que RouteDataestá disponible en ambos ControllerContexty ViewContextse puede acceder en su controlador y vistas.

También es muy fácil de probar:

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

No es necesario verificar si RouteData.DataTokenses nulo ya que esto siempre se inicializa internamente.


3

MVC Futures tiene un método AreaHelpers.GetAreaName (). Sin embargo, tenga cuidado si está utilizando este método. El uso del área actual para tomar decisiones de tiempo de ejecución sobre su aplicación podría conducir a un código difícil de depurar o inseguro.


1
¿Existe un método como ese para los controladores? Odio usar literales de cadena en una colección.
Erick T

para uso del controlador this.GetName()y para el uso del Método actualMethodBase.GetCurrentMethod().Name
Nerdroid

3

Sé que esto es antiguo, pero también, cuando está en un filtro como ActionFilter, el contexto no le proporciona fácilmente la información del área.

Se puede encontrar en el siguiente código:

var routeData = filterContext.RequestContext.RouteData;

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

Por lo tanto, el filterContext se pasa en la anulación y se encuentra el RouteData correcto en RequestContext. Hay un RoutData en el nivel Base, pero los DataTokens NO tienen el área en su diccionario.


2

Para obtener el nombre del área en la vista, en ASP.NET Core MVC 2.1:

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

2

Obtener el nombre del área en Vista (.NET Core 2.2):

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

0

Sé que esta es una publicación muy antigua, pero podemos usar la propiedad de valores exactamente de la misma manera que DataTokens

Url.RequestContext.RouteData.Values ​​["action"] funcionó para mí.


0

No sé por qué, pero la respuesta aceptada no funciona. Devuelve nulo con, por ejemplo, (tal vez sobre mvc, uso .net core)

http: // localhost: 5000 / Admin / CustomerGroup

Siempre depuro la variable y obtengo datos de ella.

Prueba esto. Esto funciona para mi

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

Ejemplo lógico detallado

Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.