Get an Episerver Page External URL for redirect back from another site

Peter Bennington
Member since: 2016
 

I need to get the external url of an Episerver page for sending to another website for use in a redirect back to my site. 

Is there built-in functionality to do this, or do I need to create a custom function such as GetExternalUrl(PageReference page)?

The external URL should look like "mysiteurl.com/somepage" instead of the relative "/somepage" URL.

Further Information: my site has the Episerver.Web.Current.SiteDefinition.SiteURL = http://mysiteurl.com, but can be accessed locally using mysiteurl.local via the additional hostname. There is also a * wildcard for scheduled jobs. Will this allow the GetExternalUrl(PageReference page) method to return the relative external link depending on the current site, e.g. if on mysiteurl.local and call GetExternalUrl(page) the link will use the .local external link instead of the .com

Any help would be greatly appreciated.

Thanks,

Peter

#199703 Dec 06, 2018 17:04
  • Johan Petersson
    Member since: 2007
     

    This should take care of most (all?) situations:

    private string GetExternalUrl(ContentReference contentLink, CultureInfo language)
    {
        var result = this.urlResolver.GetUrl(
            contentLink,
            language.Name,
            new VirtualPathArguments { ContextMode = ContextMode.Default, ForceCanonical = true });
    
        // HACK: Temprorary fix until GetUrl and ForceCanonical works as expected,
        // i.e returning an absolute URL even if there is a HTTP context that matches the page's
        // site definition and host.
        if (Uri.TryCreate(result, UriKind.RelativeOrAbsolute, out var relativeUri) &&
            relativeUri.IsAbsoluteUri == false)
        {
            var siteDefinition = this.siteDefinitionResolver.GetByContent(contentLink, true, true);
            var baseUri = siteDefinition.GetBaseUriForCulture(language);
            var absoluteUri = new Uri(baseUri, relativeUri);
    
            return absoluteUri.AbsoluteUri;
        }
    
        return result;
    }
    #199706 Edited, Dec 07, 2018 2:47
  • Peter Bennington
    Member since: 2016
     

    Hi Johan.

    Thanks for your reply. After posting my message yesterday I came across your blog post, "How to get the external URL to content" from Jan 2016. I think it is working for me, I just need to test by setting up an additional mapping in IIS to check it on different URLs. 

    My project's version of Episerver (9.5) does not contain some of the methods from the above, but the code below, which is a combination of your two samples, seems to be do what I need.

    Thanks,

    Peter

    public static string GetExternalUrl(ContentReference contentLink, CultureInfo language = null)
            {
                if (contentLink == null)
                {
                    return null;
                }
    
                if (language == null)
                {
                    language = CultureInfo.CurrentCulture;
                }
    
                var result = ServiceLocator.Current.GetInstance<UrlResolver>().GetUrl(
                    contentLink,
                    language.Name,
                    new VirtualPathArguments
                    {
                        ContextMode = ContextMode.Default,
                        ForceCanonical = true
                    });
    
                if (!Uri.TryCreate(result, UriKind.RelativeOrAbsolute, out var relativeUri) && !relativeUri.IsAbsoluteUri)
                {
                    return result;
                }
    
                var siteDefinitionResolver = ServiceLocator.Current.GetInstance<SiteDefinitionResolver>();
                var siteDefinition = siteDefinitionResolver.GetDefinitionForContent(contentLink, true, true);
    
                var hosts = siteDefinition.GetHosts(language, true).ToList();
                var host = hosts.FirstOrDefault(h => h.Type == HostDefinitionType.Primary) ?? hosts.FirstOrDefault(h => h.Type == HostDefinitionType.Undefined);
                var baseUri = siteDefinition.SiteUrl;
    
                if (host != null && host.Name.Equals("*") == false)
                {
                    // Try to create a new base URI from the host with the site's URI scheme. Name should be a valid
                    // authority, i.e. have a port number if it differs from the URI scheme's default port number.
                    Uri.TryCreate(siteDefinition.SiteUrl.Scheme + "://" + host.Name, UriKind.Absolute, out baseUri);
                }
    
                var absoluteUri = new Uri(baseUri, relativeUri);
    
                return absoluteUri.AbsoluteUri;
            }
    #199712 Edited, Dec 07, 2018 12:31
  • Peter Bennington
    Member since: 2016
     

    Actually, it is not working for me after all. It still returns the SiteDefinition.SiteUrl every time, even when accessing in IIS using mysiteurl.local

    #199722 Dec 07, 2018 12:33
  • Peter Bennington
    Member since: 2016
     

    In the end, I went with a simpler approach that works for me. Instead of using the Episerver cms values, I simply get the HttpContext.Current.Request and combine it with the Episerver ContentReference friendlyUrl retreived via the UrlResolver.GetUrl method. Full code below

    public static string GetBaseUrl()
            {
                var request = HttpContext.Current.Request;
                
                return string.Format(
                    "{0}://{1}",
                    request.Url.Scheme,
                    request.Url.Authority
                );
            }
    
            public static string GetExternalUrl(ContentReference contentLink)
            {
                var baseUrl = GetBaseUrl();
    
                if (baseUrl.EndsWith("/"))
                {
                    baseUrl = baseUrl.TrimEnd('/');
                }
    
                var contentPath = ServiceLocator.Current.GetInstance<UrlResolver>().GetUrl(contentLink);
    
                if (!contentPath.StartsWith("/"))
                {
                    contentPath += '/';
                }
    
                return string.Concat(baseUrl, contentPath);
            }

    #199734 Dec 07, 2018 18:16