Как получить имя текущей области в представлении или контроллере?
Есть ли что-то вроде ViewContext.RouteData.Values["controller"]
для областей?
Как получить имя текущей области в представлении или контроллере?
Есть ли что-то вроде ViewContext.RouteData.Values["controller"]
для областей?
Начиная с MVC2 вы можете использовать ViewContext.RouteData.DataTokens["area"]
HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"]
Вы можете получить его с контроллера, используя:
ControllerContext.RouteData.DataTokens["area"]
Я только что написал ab запись в журнале об этом, вы можете посетить это для более подробной информации, но мой ответ заключался в том, чтобы создать метод расширения, показанный ниже.
Ключевым кикером было то, что вы вытягиваете область MVC из .DataTokens и контроллера/действия из .Values 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;
}
Затем вы можете реализовать его, как показано ниже:
<ul id="menu">
@Html.TopMenuLink("Dashboard", "Home", "Index", "", "Click here for the dashboard.")
@Html.TopMenuLink("Courses", "Home", "Index", "Courses", "List of our Courses.")
</ul>
Я создал метод расширения для RouteData
, который возвращает имя текущей области.
public static string GetAreaName(this RouteData routeData)
{
object area;
if (routeData.DataTokens.TryGetValue("area", out area))
{
return area as string;
}
return null;
}
Так как RouteData
доступен как для ControllerContext
, так и для ViewContext
, он может быть доступен в вашем контроллере и представлениях.
Также очень легко проверить:
[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();
}
}
Нет необходимости проверять, является ли RouteData.DataTokens
нулевым, поскольку это всегда инициализировано внутри.
В ASP.NET Core 1.0 значение находится в
ViewContext.RouteData.Values [ "area"];
MVC Futures имеет метод AreaHelpers.GetAreaName(). Однако будьте осторожны, если вы используете этот метод. Использование текущей области для принятия решений во время выполнения вашего приложения может привести к сложному отлаживанию или небезопасному коду.
Я знаю, что это старый, но также, когда в фильтре, таком как ActionFilter, контекст не просто предоставляет вам информацию о зоне.
Его можно найти в следующем коде:
var routeData = filterContext.RequestContext.RouteData;
if (routeData.DataTokens["area"] != null)
area = routeData.DataTokens["area"].ToString();
Таким образом, filterContext передается при переопределении, и правильная RouteData находится в RequestContext. На базовом уровне есть RoutData, но в DataTokens НЕ есть область в нем.
Я знаю, что это очень старый пост, но мы можем использовать свойство Values точно так же, как DataTokens
Url.RequestContext.RouteData.Values [ "action" ] работал у меня.
Чтобы получить имя области в представлении, в ASP.NET Core MVC 2.1:
@Context.GetRouteData().Values["area"]
Получить имя области в View (.NET Core 2.2):
ViewContext?.ActionDescriptor?.RouteValues["area"]