AI OnAI Off
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.