X++: How to get the D365FO URL correctly inside backend services

You may need to retrieve the URL of the D365 FO instance for logging or integration purposes, or for generating deep links. D365 FO foundation package provides you the URLUtility::getUrl() method for this. However this FO standard method does not work if you execute it from a batch or inside a custom API service. When we step into the code we see that it calls this method in Global class :

    /// <summary>
    /// Gets the current request uri
    /// </summary>
    /// <returns>the current request uri</returns>
    internal static System.Uri GetCurrentUri()
    {
        Microsoft.Dynamics.Client.ServerForm.Contexts.SessionContext sessionContext;
        System.Uri currentUrl = null;

        sessionContext = Microsoft.Dynamics.Client.ServerForm.Contexts.SessionContext::get_Current();
        if (sessionContext)
        {
            currentUrl = sessionContext.get_RequestUrl();
        }

        return currentUrl;
    }

Here is uses the SessionContext of ASP.NET to get the current URL. However if there is no browser session open, like in the case of services or batch runs, there is also no SessionContext and this code fails.

In that case we have other ASP.NET methods to get the URL, such as “HttpContext.Current.Request.Url.AbsoluteUri”, but the HttpContext is also not available inside X++ and I could not find any standard FO code that uses it (if you know a place that uses it, please feel free to share it in the comments). Upon further investigation for that, I have found this call which works perfectly in backend services as well :

using Microsoft.Dynamics.ApplicationPlatform.Environment;

..................
..................

IApplicationEnvironment env = EnvironmentFactory::GetApplicationEnvironment();
str currentUrl = env.Infrastructure.HostUrl;
System.Uri currentHost = new System.Uri(currentUrl);

Then to get the root path of the URL you can use:

str hostUrl = currentHostUrl.GetLeftPart(System.UriPartial::Authority);

To generate deeplinks using this code, put it inside your own utility class and use the it in this blog post replacing the URLUtility::getUrl() call with your own.

Comment List
Anonymous
Related
Recommended