Search code examples
c#asp.net-mvcepiserver

How can I extract a friendly URL from an EpiServer PageData object?


Using EpiServer 8.0, we need to get the "friendly" URL from a PageData object within a C# class. Without converting the URL, internal links look like "localhost/link/[guid].aspx" instead of "localhost/friendly-link". I've seen online posts that suggest the following:

var urlHelper = ServiceLocator.Current.GetInstance<UrlHelper>();
var friendlyUrl = urlHelper.ContentUrl(currentPage.Link);

But when I attempt this, Visual Studio returns the following error:

'System.Web.Mvc.UrlHelper' does not contain a definition for 'ContentUrl' and no extension method 'ContentUrl' accepting a first argument of type 'System.Web.Mvc.UrlHelper' could be found (are you missing a using directive or an assembly reference?)

Here is the code I presently have, without using statements so it's easy to see the namespaces that are being used.

var urlHelper = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<System.Web.Mvc.UrlHelper>();
var friendlyUrl = urlHelper.ContentUrl(myPage.Link);

Are we missing a reference in our project to make ContentUrl work? Or is there some alternate code we can employ to get a friendly URL from a PageData object? Thanks for your help.


Solution

  • You should be using the UrlResolver class

    using System.Web.Routing;
    using EPiServer.Web.Routing;
    
    public static class PageDataExtensions
    {
    
        public static VirtualPathData FriendlyUrl(this ContentReference contentReference)
        {
            return ServiceLocator.Current.GetInstance<UrlResolver>().GetVirtualPath(contentReference);
            // or use the singleton
            // return UrlResolver.Current.GetVirtualPath(contentReference); 
        }
    
        public static VirtualPathData FriendlyUrl(this PageData pageData)
        {
            var contentReference = pageData.ContentLink;
            return ServiceLocator.Current.GetInstance<UrlResolver>().GetVirtualPath(contentReference);
            // or use the singleton
            // return UrlResolver.Current.GetVirtualPath(contentReference); 
        }
    
        public static VirtualPathData FriendlyUrl(this IContent iContent)
        {
            var contentReference = iContent.ContentLink;
            return ServiceLocator.Current.GetInstance<UrlResolver>().GetVirtualPath(contentReference);
            // or use the singleton
            // return UrlResolver.Current.GetVirtualPath(contentReference); 
        }
    }
    

    This will return a VirtualPathData object that have the property VirtualPath

    In your case

    var friendlyUrl = currentPage.FriendlyUrl().VirtualPath; // using the extensions above
    

    would return friendly-url/whatever/page