Try our conversational search powered by Generative AI!

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

Vote:
 

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
Vote:
 

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:42
Vote:
 

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 10:51
Vote:
 

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
Vote:
 

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
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.