Як отримати назву поточної області у вікні чи контролері?
Чи є щось подібне ViewContext.RouteData.Values["controller"]
для районів?
Як отримати назву поточної області у вікні чи контролері?
Чи є щось подібне ViewContext.RouteData.Values["controller"]
для районів?
Відповіді:
З MVC2 можна використовувати ViewContext.RouteData.DataTokens["area"]
ASP.NET Core 1.0
замість MVC6
.. :-)
Ви можете отримати його від контролера, використовуючи:
ControllerContext.RouteData.DataTokens["area"]
У ASP.NET Core 1.0 значення знайдено в
ViewContext.RouteData.Values ["область"];
pageModel.RouteData.Values.TryGetValue("area", out object 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>
area
лексему в тому, що Values
потрібно, але мені потрібно було подивитися в DataTokens
... поняття, чому.
Я створив метод розширення для 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
є нульовим, оскільки це завжди ініціалізується внутрішньо.
MVC Futures має метод AreaHelpers.GetAreaName (). Однак будьте обережні, якщо ви використовуєте цей метод. Використання поточної області для прийняття рішень виконання програми щодо вашої програми може призвести до важкої налагодження чи незахищеного коду.
this.GetName()
та для поточного використання методуMethodBase.GetCurrentMethod().Name
Я знаю, що це старе, але також, коли у фільтрі, як ActionFilter, контекст не може легко надати вам інформацію про область.
Його можна знайти в наступному коді:
var routeData = filterContext.RequestContext.RouteData;
if (routeData.DataTokens["area"] != null)
area = routeData.DataTokens["area"].ToString();
Таким чином, filterContext передається на заміщення, і правильний RouteData знаходиться під RequestContext. На базовому рівні є RoutData, але DataTokens НЕ має області в своєму словнику.
Я знаю, що це дуже давня публікація, але ми можемо використовувати властивість Значення точно так само, як і DataTokens
Url.RequestContext.RouteData.Values ["дія"] працював на мене.
Я не знаю чому, але прийнята відповідь не працює. Він повертає null з, наприклад (можливо, про mvc, я використовую .net core)
Я завжди налагоджую змінну і отримую дані з неї.
Спробуйте це. Це працює для мене
var area = ViewContext.RouteData.Values["area"]
Детальний логічний приклад
Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";