November Happy Hour will be moved to Thursday December 5th.
AI OnAI Off
November Happy Hour will be moved to Thursday December 5th.
Hi,
Below is an extension method (for UrlHelper) that lets you generate Url's to specific actions on page controllers:
e.g. Url.PageUrl(myPage, "SomeAction", new { someMethodParamater : parameterValue })
public static MvcHtmlString PageUrl(this UrlHelper instance, PageData page, string action, object routeValues) { var rvd = new RouteValueDictionary(routeValues); var urlBuilder = new UrlBuilder(HttpUtility.HtmlDecode(page.LinkURL)); var languageForRequest = GetLanguageForRequest(urlBuilder, instance.RequestContext); var shouldSetIdAsQueryParameter = ShouldSetIdAsQueryParameter(instance.RequestContext); var newRequestContext = new RequestContext {RouteData = new RouteData()}; // Build the new route values up based on the existing request, // the additional route values passed and the new action rvd.Add("action", action); if (instance.RequestContext.GetIgnorePartialRouting()) { rvd.Add("ignorePartialRouting", true); } if (shouldSetIdAsQueryParameter) { rvd.Add("id", page.PageLink.ToString()); } if (PageEditing.PageIsInEditMode) { newRequestContext.RouteData.DataTokens["contextmode"] = ContextMode.Edit; } var epichannel = PageEditing.GetChannel(instance.RequestContext.HttpContext); if (!string.IsNullOrEmpty(epichannel)) { rvd.Add("epichannel", epichannel); } var urlResolver = new UrlResolver(instance.RouteCollection, null, null); return new MvcHtmlString(urlResolver.GetVirtualPath(page.PageLink, languageForRequest, rvd, newRequestContext).GetUrl()); }
Here's the whole class, which you will need to compile the snippet
using System.Web; using System.Web.Mvc; using System.Web.Routing; using EPiServer; using EPiServer.Core; using EPiServer.Editor; using EPiServer.Globalization; using EPiServer.ServiceLocation; using EPiServer.Web; using EPiServer.Web.Mvc.Html; using EPiServer.Web.Routing; namespace <Putyournamespacehere> { public static class UrlExtension { // cheater to fix app_code helpers.cshtml. Cannot call helper extensions from app_code in mvc public static IHtmlString PageLinkUrl(PageReference pageLink) { if (ContentReference.IsNullOrEmpty(pageLink)) { return MvcHtmlString.Empty; } var urlResolver = ServiceLocator.Current.GetInstance<UrlResolver>(); var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>(); var page = contentLoader.Get<PageData>(pageLink); return new MvcHtmlString(urlResolver.GetVirtualPath(page.PageLink)); } /// <summary> /// Returns the target URL for a PageReference. Respects the page's shortcut setting /// so if the page is set as a shortcut to another page or an external URL that URL /// will be returned. /// </summary> public static IHtmlString PageLinkUrl(this UrlHelper urlHelper, PageReference pageLink) { if (ContentReference.IsNullOrEmpty(pageLink)) { return MvcHtmlString.Empty; } var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>(); var page = contentLoader.Get<PageData>(pageLink); return PageLinkUrl(urlHelper, page); } /// <summary> /// Returns the target URL for a page. Respects the page's shortcut setting /// so if the page is set as a shortcut to another page or an external URL that URL /// will be returned. /// </summary> public static IHtmlString PageLinkUrl(this UrlHelper urlHelper, PageData page) { var urlResolver = ServiceLocator.Current.GetInstance<UrlResolver>(); switch (page.LinkType) { case PageShortcutType.Normal: case PageShortcutType.FetchData: return new MvcHtmlString(urlResolver.GetVirtualPath(page.PageLink)); case PageShortcutType.Shortcut: var shortcutProperty = page.Property["PageShortcutLink"] as PropertyPageReference; if (shortcutProperty != null && !ContentReference.IsNullOrEmpty(shortcutProperty.PageLink)) { return urlHelper.PageLinkUrl(shortcutProperty.PageLink); } break; case PageShortcutType.External: return new MvcHtmlString(page.LinkURL); } return MvcHtmlString.Empty; } public static RouteValueDictionary GetPageRoute(this RequestContext requestContext, PageReference pageLink) { var values = new RouteValueDictionary(); values[RoutingConstants.NodeKey] = pageLink; values[RoutingConstants.LanguageKey] = ContentLanguage.PreferredCulture.Name; var idkeep = requestContext.HttpContext.Request.QueryString["idkeep"]; if (idkeep != null && !PageReference.IsNullOrEmpty(pageLink)) { values["id"] = pageLink.ToString(); } return values; } public static string Content(this UrlHelper instance, Url contentPath) { if (contentPath == null) { return null; } return instance.Content(contentPath.ToString()); } public static MvcHtmlString PageUrl(this UrlHelper instance, PageReference pageReference) { return PageUrl(instance, pageReference.GetPage(), null); } public static MvcHtmlString PageUrl(this UrlHelper instance, PageReference pageReference, object routeValues) { return PageUrl(instance, pageReference.GetPage(), routeValues); } public static MvcHtmlString PageUrl(this UrlHelper instance, PageReference pageReference, string action, object routeValues) { return PageUrl(instance, pageReference.GetPage(), action, routeValues); } public static MvcHtmlString PageUrl(this UrlHelper instance, PageData page) { return PageUrl(instance, page, null); } public static MvcHtmlString PageUrl(this UrlHelper instance, PageData page, object routeValues) { return PageUrl(instance, page, "Index", routeValues); } public static MvcHtmlString PageUrl(this UrlHelper instance, PageData page, string action, object routeValues) { var rvd = new RouteValueDictionary(routeValues); var urlBuilder = new UrlBuilder(HttpUtility.HtmlDecode(page.LinkURL)); var languageForRequest = GetLanguageForRequest(urlBuilder, instance.RequestContext); var shouldSetIdAsQueryParameter = ShouldSetIdAsQueryParameter(instance.RequestContext); var newRequestContext = new RequestContext {RouteData = new RouteData()}; // Build the new route values up based on the existing request, // the additional route values passed and the new action rvd.Add("action", action); if (instance.RequestContext.GetIgnorePartialRouting()) { rvd.Add("ignorePartialRouting", true); } if (shouldSetIdAsQueryParameter) { rvd.Add("id", page.PageLink.ToString()); } if (PageEditing.PageIsInEditMode) { newRequestContext.RouteData.DataTokens["contextmode"] = ContextMode.Edit; } var epichannel = PageEditing.GetChannel(instance.RequestContext.HttpContext); if (!string.IsNullOrEmpty(epichannel)) { rvd.Add("epichannel", epichannel); } var urlResolver = new UrlResolver(instance.RouteCollection, null, null); return new MvcHtmlString(urlResolver.GetVirtualPath(page.PageLink, languageForRequest, rvd, newRequestContext).GetUrl()); } public static MvcHtmlString PageUrl(this UrlHelper urlHelper, Url url) { if (url == null) { return null; } if (url.IsEmpty()) { return MvcHtmlString.Empty; } return urlHelper.PageUrl(classicUrl: url.ToString()); } public static bool IsNullOrEmpty(this Url contentPath) { if (contentPath == null) { return true; } if (contentPath.IsEmpty()) { return true; } return false; } private static string GetLanguageForRequest(UrlBuilder urlBuilder, RequestContext requestContext) { var language = urlBuilder.QueryCollection["epslanguage"]; if (string.IsNullOrWhiteSpace(language)) { language = (requestContext.GetLanguage() ?? ContentLanguage.PreferredCulture.Name); } return language; } private static bool ShouldSetIdAsQueryParameter(RequestContext requestContext) { var setIdAsQueryParameter = false; bool flag; if (!string.IsNullOrEmpty(requestContext.HttpContext.Request.QueryString["idkeep"]) && !bool.TryParse(requestContext.HttpContext.Request.QueryString["idkeep"], out flag)) { setIdAsQueryParameter = flag; } return setIdAsQueryParameter; } /* private static string MapUrlFromRoute(RequestContext requestContext, RouteCollection routeCollection, string url) { UrlBuilder urlBuilder = new UrlBuilder(HttpUtility.HtmlDecode(url)); ContentReference contentReference = PermanentLinkUtility.GetContentReference(urlBuilder); if (!ContentReference.IsNullOrEmpty(contentReference)) { string text = urlBuilder.QueryCollection["epslanguage"]; if (text == null) { text = (requestContext.GetLanguage() ?? ContentLanguage.PreferredCulture.Name); } bool setIdAsQueryParameter = false; bool flag; if (!string.IsNullOrEmpty(requestContext.HttpContext.Request.QueryString["idkeep"]) && !bool.TryParse(requestContext.HttpContext.Request.QueryString["idkeep"], out flag)) { setIdAsQueryParameter = flag; } VirtualPathData virtualPath = GetVirtualPath(routeCollection, contentReference, text, setIdAsQueryParameter, false); return virtualPath.GetUrl(); } return urlBuilder.ToString(); } private static VirtualPathData GetVirtualPath(RouteCollection routes, ContentReference contentLink, string language, bool setIdAsQueryParameter, bool forceIsInEditMode) { RequestContext requestContext = new RequestContext(); requestContext.RouteData = new RouteData(); RouteValueDictionary routeValueDictionary = new RouteValueDictionary(); RequestContext requestContext2 = HttpContext.Current.GetRequestContext(); if (forceIsInEditMode || (requestContext2 != null && requestContext2.GetIgnorePartialRouting())) { routeValueDictionary.Add(RoutingConstants.IgnorePartialRoutingKey, true); } if (setIdAsQueryParameter) { routeValueDictionary.Add(RoutingConstants.IdKey, contentLink.ToString()); } if (forceIsInEditMode || PageEditing.PageIsInEditMode) { requestContext.SetContextMode(ContextMode.Edit); } string value = (requestContext2 != null) ? PageEditing.GetChannel(requestContext2.HttpContext) : null; if (!string.IsNullOrEmpty(value)) { routeValueDictionary.Add("epichannel", value); } UrlResolver urlResolver = new UrlResolver(routes, null, null); return urlResolver.GetVirtualPath(contentLink, language, routeValueDictionary, requestContext); }*/ } }
Hi, I'm wondering if it's possible to connect a specific PageLink from my nav to a specific action in the controller?
I'm trying to recreate my company's intranet as an assignment for my internship here, and I'm trying to keep the code to a minimum, with the same functionality and design - but with editorial properties etc.
I'm using a modified version of Joel Abrahamssons NavigationHelper(RenderMainNavigation) that simply creates tablerows and data inside a table instead of an UL, but I want to associate each PageLink with a specific action without creating a ton of different controllers.
As an example:
I have the startpage in the nav, and when I click it I want it to go to the action Index.
I also have a profilepage in the nav, and when I click that link I would like it to go to a different action in the same controller (even though it's a different pagetype) and return a different view inside a @section.
I currently have no built up code for any of this except the NavigationHelper class, but I'm wondering if this is possible or if there's another, better way or if I should just give up and do it the normal way.
Thanks in advance.