9 ответов:
Я только что написал bзапись в журнале об этом, вы можете посетить для получения более подробной информации, но мой ответ был создать метод расширения, как показано ниже.
ключевым кикером было то, что вы вытаскиваете область MVC из .DataTokens и контроллер/действие от .Значения 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имеет значение null, так как это всегда инициализируется внутри.
Я знаю, что это старый, но также, когда в фильтре, таком как ActionFilter, контекст не легко предоставляет вам информацию о области.
его можно найти в следующем коде:
var routeData = filterContext.RequestContext.RouteData; if (routeData.DataTokens["area"] != null) area = routeData.DataTokens["area"].ToString();таким образом, filterContext передается в переопределении, и правильные RouteData находятся под RequestContext. Существует RoutData на базовом уровне, но DataTokens не имеют области в его словаре.
MVC Futures имеет AreaHelpers.Метод GetAreaName (). Однако, будьте осторожны, если вы используете этот метод. Использование текущей области для принятия решений во время выполнения для вашего приложения может привести к трудной отладке или небезопасному коду.
Я знаю, что это очень старый пост, но мы можем использовать свойство Values точно так же, как DataTokens
Url.RequestContext.RouteData.Ценности ["действие"] работали на меня.
Comments