¿Cómo se obtiene el nombre del área actual en la vista o controlador?
¿Hay algo parecido ViewContext.RouteData.Values["controller"]
a las áreas?
¿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:
Desde MVC2 en adelante puedes usar ViewContext.RouteData.DataTokens["area"]
ASP.NET Core 1.0
lugar de MVC6
... :-)
Puede obtenerlo del controlador usando:
ControllerContext.RouteData.DataTokens["area"]
En ASP.NET Core 1.0, el valor se encuentra en
ViewContext.RouteData.Values ["área"];
pageModel.RouteData.Values.TryGetValue("area", out object area)
debería usarse en su lugar)
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>
area
token en el, Values
pero necesitaba buscar en el DataTokens
... no tengo idea de por qué.
Creé un método de extensión para RouteData
que 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 RouteData
está disponible en ambos ControllerContext
y ViewContext
se 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.DataTokens
es nulo ya que esto siempre se inicializa internamente.
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.
this.GetName()
y para el uso del Método actualMethodBase.GetCurrentMethod().Name
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.
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í.
No sé por qué, pero la respuesta aceptada no funciona. Devuelve nulo con, por ejemplo, (tal vez sobre mvc, uso .net core)
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";