Skip to main content

Notifications

Announcements

No record found.

Finance | Project Operations, Human Resources, ...
Unanswered

Call AccessToken DLL error: Could not load type 'System.Threading.Tasks.Task`1' from assembly '

(2) ShareShare
ReportReport
Posted on by 590
Hi,
 
I want to create DLL which at first will get an AccessToken from Azure. Here are the steps:
1. Create C# project, there is these methods:
     
    public async Task<string> GetAccessTokenAsync(string authUrl, string clientId, string clientSecret, string scope)
        {
            var client = new HttpClient();
            var tokenRequest = new FormUrlEncodedContent(new[] {
                new KeyValuePair < string, string > ("grant_type", "client_credentials"),
                new KeyValuePair < string, string > ("client_id", clientId),
                new KeyValuePair < string, string > ("client_secret", clientSecret),
                new KeyValuePair < string, string > ("scope", scope)
                });
            for (int i = 1; i <= NumberOfRetries; ++i)
            {
                try
                {
                    HttpResponseMessage response = await client.PostAsync(authUrl, tokenRequest);
                    response.EnsureSuccessStatusCode();
                    string content = await response.Content.ReadAsStringAsync();
                    dynamic jsonResponse = JsonConvert.DeserializeObject(content);  //must declare using Newtonsoft.Json;
                    return jsonResponse.access_token;
                }
                catch (Exception ex)
                {
                    if (i != NumberOfRetries)
                    {
                        await Task.Delay(DelayOnRetry);
                    }
                    else
                    {
                        LogError("GetAccessTokenAsync", ex);
                        string v = $"Error: {ex.Message}";
                        return v;
                    }
                }
            }
            return null;
        }
        /// <summary>
        /// 1. Avoid Asynchronous Methods in X++, X++ does not natively support asynchronous methods(async and await) and Task-based programming like C#.
        /// 2. Sync Method (GetAccessToken): Uses task.Wait() and task.Result to synchronously wait for the async operation to complete.
        /// </summary>
        /// <param name="authUrl"></param>
        /// <param name="clientId"></param>
        /// <param name="clientSecret"></param>
        /// <param name="scope"></param>
        /// <returns></returns>
        public string GetAccessToken(string authUrl, string clientId, string clientSecret, string scope)
        {
            try
            {
                // Blocking call to ensure the method is synchronous
                var task = GetAccessTokenAsync(authUrl, clientId, clientSecret, scope);
                task.Wait(); // Wait for the async task to complete
                return task.Result; // Retrieve the result
            }
            catch (AggregateException aggEx)
            {
                // Handle potential AggregateException from task.Wait()
                for (int i = 0; i < aggEx.InnerExceptions.Count; i++)
                {
                    Exception ex = aggEx.InnerExceptions[i];
                    LogError("GetAccessToken", ex);
                }
                return $"Error: {aggEx.Message}";
            }
            catch (Exception ex)
            {
                // Handle any other exceptions
                LogError("GetAccessToken", ex);
                return $"Error: {ex.Message}";
            }
        }
    }
  
2. Rebuild this class. The DLL file is saved in its default location <my project folder> / bin / debug
 
3. I have created X++ class to consume the DLL, have added the reference to the DLL (am not moving the DLL file, so it is still in the same path as in point 2). And inside this class, have this method:
 
   
   class A_Integration_General
   {
      /// <summary>
      /// Get Access Token
      /// </summary>
      /// <returns>Access Token as a string</returns>
      public static System.String getAccessToken()
      {
        //SystemParameters    systemParameters = SystemParameters::find();        
        System.String       clientId        = "d365fo.client";
        System.String       clientSecret    = "ixxxxxxxxxxxxxxxxxxxxxx";
        System.String       scope           = "xxxxxxAPI";
        System.String       IntegrationUrl  = "https://xxxxxxxx/connect/token";
        System.String       accessToken;

        // Instantiate the DLL object directly
        A_Integration.A_ConnectionUtils connection = new A_Integration.A_ConnectionUtils();
        // Call the method directly without using reflection
        accessToken = connection.GetAccessToken(IntegrationUrl, clientId, clientSecret, scope);
               
        return accessToken;
      }
  }
 
4. Create Runnable class for testing :
 
   
   internal final class A_TestCallDLL
   { 
    
      public static void main(Args _args)
      {
        System.String accessToken;
        try
        {
            // Call the getAccessToken method from your custom class
            accessToken = A_Integration_General::getAccessToken();
            // Display the access token in the infolog
            info(strFmt("Access Token: %1", accessToken));
        }
        catch (Exception::CLRError)
        {
            // Handle any CLR errors that occur during the call
            info("An error occurred while retrieving the access token.");
            throw error(AifUtil::getClrErrorMessage());
        }
        catch (Exception::Error)
        {
            // Handle any other X++ errors
            info("An X++ error occurred.");
            throw;
        }
      }
  }
 
5. Build model. Succeeded with no error.
 
However, when calling this runnable class on frontend (D365 FO UI), I keep getting this error : Could not load type 'System.Threading.Tasks.Task`1' from assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
 
May I know how to resolve this ? I have limited knowledge regarding this, if I googled it is something about X++ didn't support Async, but I already tried to add the method to make it as sync with method "getAccessToken" in my C# DLL. May I know what did I missed ?
 
Thanks
 
 
 
 
 
 
 
 
 
 
 
 
  • Voltes Profile Picture
    Voltes 590 on at
    Call AccessToken DLL error: Could not load type 'System.Threading.Tasks.Task`1' from assembly '
    Hi Martin,
     
    Thanks for your reply. While being new to DLL programming, if I'm guessing correctly, I think this is because when first choose Project Template, I'm choosing the wrong one, can I say that ?
     
    If I take a look again, I'm choosing Universal Windows for the template:
     
    While actually I should choose the ".Net Framework", isn't this correct ?
     
    Noted about many blog of this, but apparently it is too many which I don't know which one is the correct one, especially in relate to create DLL for D365 F&O.
     
    Thanks again.
     
     
     
  • Martin Dráb Profile Picture
    Martin Dráb 230,371 Most Valuable Professional on at
    Call AccessToken DLL error: Could not load type 'System.Threading.Tasks.Task`1' from assembly '
    You mentioned you want to create a DLL, which seems to mean a .NET assembly created from a C# project. When you create a .NET project (e.g. a C# class library), you need to decide which kind and version of framework it'll be for. For example, you can't build your code for .NET Core 2.0 and then use it in .NET Framework 4.5 application.
     
    You make one decision when selecting the project template and then you can adjust the version in project properties. Also, don't forget that there is documentation to follow (Framework targeting overview) and plenty of other information sources on Internet.
  • Voltes Profile Picture
    Voltes 590 on at
    Call AccessToken DLL error: Could not load type 'System.Threading.Tasks.Task`1' from assembly '
    Hi everyone,
     
    Is there some feedback on this?
     
    Thanks.
  • Voltes Profile Picture
    Voltes 590 on at
    Call AccessToken DLL error: Could not load type 'System.Threading.Tasks.Task`1' from assembly '
    Hi Martin,
     
    May I know what you mean by target framework ?
     
    I'm sorry I'm new to this Integration thing, but what I had in mind is later I will create X++ class for a batch job, and it will retrieve data from the 3rd party. So I already have the 3rd party URL address for me get their data. This batch job will then insert the data to my staging table in D365 F&O.
     
    The next part will be processing this staging table to F&O main table. Does this make sense ? and answering your question ?
     
    Thanks.
  • Martin Dráb Profile Picture
    Martin Dráb 230,371 Most Valuable Professional on at
    Call AccessToken DLL error: Could not load type 'System.Threading.Tasks.Task`1' from assembly '
    What is the target framework of your C# project?
     
    By the way, there is now an easier way of catching CLR exceptions in X++:
    System.Exception ex;
    
    try
    {
        ...
    }
    catch (ex)
    {
        // Example of accessing properties
        str message = ex.Message;
    }

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Congratulations 2024 Spotlight Honorees!

Kudos to all of our 2024 community stars! 🎉

Meet the Top 10 leaders for December!

Congratulations to our December super stars! 🥳

Get Started Blogging in the Community

Hosted or syndicated blogging is available! ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,642 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,371 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans