asp.net mvc 2 - una - ASP.NET MVC: obtenga el nombre del área actual en la vista o el controlador
razor para mvc (9)
Acabo de escribir una entrada de registro de ab sobre esto , puedes 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 los .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;
}
Entonces puedes 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>
¿Cómo se obtiene el nombre del área actual en la vista o el controlador?
¿Hay algo como ViewContext.RouteData.Values["controller"]
para las áreas?
En ASP.NET Core 1.0, el valor se encuentra en
ViewContext.RouteData.Values ["area"];
En MVC 2 puede usar ViewContext.RouteData.DataTokens["area"]
Puedes obtenerlo del controlador usando:
ControllerContext.RouteData.DataTokens["area"]
Sé que esta es una publicación muy antigua, pero podemos usar la Propiedad de Valores exactamente de la misma manera que los DataTokens
Url.RequestContext.RouteData.Values ["action"] funcionó para mí.
Sé que esto es viejo, pero también, cuando 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 filtroContext se transfiere en la anulación y el RouteData correcto se encuentra debajo de RequestContext. Hay un RoutData en el nivel Base, pero los DataTokens NO tienen el área en su diccionario.
MVC Futures tiene un método AreaHelpers.GetAreaName (). Sin embargo, tenga cuidado si usa este método. Usar el área actual para tomar decisiones de tiempo de ejecución sobre su aplicación podría llevar a un código difícil de depurar o inseguro.
RouteData
un método de extensión para RouteData
que devuelve 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;
}
Como RouteData
está disponible tanto en ControllerContext
como en ViewContext
se puede acceder a él 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 comprobar si RouteData.DataTokens
es nulo, ya que esto siempre se inicializa internamente.
HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"]