web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

D365FO and .net dll

(3) ShareShare
ReportReport
Posted on by 107
Hello, I am trying to create a helper class in x++ that will upload files to Azure blob storage.
 
First I used Microsoft.WindowsAzure.Storage dll and it worked fine. But then I found that this package has been deprecated https://www.nuget.org/packages/microsoft.azure.storage.blob/ so I tried to rewrite the code using the recomended package Azure.Storage.Blobs.
Both Microsoft.WindowsAzure.Storage and Azure.Storage.Blobs are included in AosService\PackagesLocalDirectory\bin so we can reference them diractly in x++ code.
 
The problem is that containerClient.CreateIfNotExists() from Azure.Storage.Blobs does not compile and throwing bunch of errors
 
Azure.Storage.Blobs Code (throws errors on the first lines):
 public static void uploadBlob(System.IO.MemoryStream file, str fileName, str connectionString, str containerName, int expireMinutes = 5)
 {
     // Create a BlobServiceClient using the connection string
     Azure.Storage.Blobs.BlobServiceClient blobServiceClient = new Azure.Storage.Blobs.BlobServiceClient(connectionString);
     
     // Get a reference to the container
     Azure.Storage.Blobs.BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("ponta");
     
     // Create the container if it doesn't exist
     containerClient.CreateIfNotExists(); 
     
     ...
 
}
 
Errors:
Severity    Code    Description    Project    File    Line    Suppression State
Error        The "BuildTask" task returned false but did not log an error.    ExportInvoice (ISV) [ISAIS]    C:\Program Files (x86)\MSBuild\Microsoft\Dynamics\AX\Microsoft.Dynamics.Framework.Tools.BuildTasks.17.0.targets    63    
Error        Cannot convert the default value of the 'IDictionary`2' parameter of method 'CreateIfNotExists' on CLR type 'Azure.Storage.Blobs.BlobContainerClient' because it cannot be converted to a valid X++ literal. Pass a literal value for 'IDictionary`2' instead.    ExportInvoice (ISV) [ISAIS]    K:\AosService\PackagesLocalDirectory\bin\XppSource\ISAIS\AxClass_ISAIS_AzureStorageAccountHelper.xpp    17    
Error        Cannot convert the default value of the 'CancellationToken' parameter of method 'CreateIfNotExists' on CLR type 'Azure.Storage.Blobs.BlobContainerClient' because it cannot be converted to a valid X++ literal. Pass a literal value for 'CancellationToken' instead.    ExportInvoice (ISV) [ISAIS]    K:\AosService\PackagesLocalDirectory\bin\XppSource\ISAIS\AxClass_ISAIS_AzureStorageAccountHelper.xpp    17    
Error        Cannot convert the default value of the 'BlobContainerEncryptionScopeOptions' parameter of method 'CreateIfNotExists' on CLR type 'Azure.Storage.Blobs.BlobContainerClient' because it cannot be converted to a valid X++ literal. Pass a literal value for 'BlobContainerEncryptionScopeOptions' instead.    ExportInvoice (ISV) [ISAIS]    K:\AosService\PackagesLocalDirectory\bin\XppSource\ISAIS\AxClass_ISAIS_AzureStorageAccountHelper.xpp    17    

I now started to wonder is worth it to write this kind of logic in x++ or just write it in .net and reference it in x++.
What do you think, what are Pros and Cons?
 
 
 
 
 
 
Categories:
I have the same question (0)
  • Martin Dráb Profile Picture
    236,503 Most Valuable Professional on at
    D365FO and .net dll
    Regarding "Cannot convert the default value of the 'CancellationToken' parameter of method 'CreateIfNotExists' on CLR type 'Azure.Storage.Blobs.BlobContainerClient' because it cannot be converted to a valid X++ literal. Pass a literal value for 'CancellationToken' instead.", the message already contains a suggested solution. Have you tried it?
  • Suggested answer
    Anton Venter Profile Picture
    20,301 Super User 2025 Season 2 on at
    D365FO and .net dll
    Looking at the stack trace, there is a clue there. Have you tried to pass the default value instead of leaving it empty?

    "...Pass a literal value for 'BlobContainerEncryptionScopeOptions' instead...."
     
    As far as the pros and cons go, with these kiund of things, I always to try to do as much as possible in X++. This reduces dependencies.
  • tdgscorpion Profile Picture
    107 on at
    D365FO and .net dll
    I already tried create these objects

    Azure.Storage.Blobs.Models.PublicAccessType publicAccessType = Azure.Storage.Blobs.Models.PublicAccessType::None;
     
    and 
     
    Azure.Storage.Blobs.Models.BlobContainerEncryptionScopeOptions encryptionScopeOptions = null;
     
    are fine but could not create 

    System.Collections.Generic.IDictionary`2 metadata
     
    and 
     
    System.Threading.CancellationToken cancellationToken
     
    these types throw errors
    System.Collections.Generic.IDictionary`2 is sintactical, I don`t know what is this `2
    and CancellationToken is not found in System.Threading

     
  • CU07020437-0 Profile Picture
    2 on at
    D365FO and .net dll
    Hello, where you able to fix this error? Please let me know if you did. 
  • Martin Dráb Profile Picture
    236,503 Most Valuable Professional on at
    D365FO and .net dll
    System.Collections.Generic.IDictionary`2 is a generic collection; you can't write it like that. X++ doesn't support generics, therefore if you want to do things like declare generic types, you'll be better off writing a C# library (and calling this library from X++) then trying to do it directly in X++. There is a good chance that it'll solve the original problem as well; just make sure that your C# library uses the same assembly versions as F&O.
  • Suggested answer
    Gerhard Rieser Profile Picture
    6 on at
    D365FO and .net dll
    Hello,
    for me following code works:
     
    BlobContainerClient blobContainer = blobServiceClient.GetBlobContainerClient(_blobContainerName);
    Azure.Storage.Blobs.Models.PublicAccessType publicAccessType = Azure.Storage.Blobs.Models.PublicAccessType::None;
    Azure.Storage.Blobs.Models.BlobContainerEncryptionScopeOptions encryptionScopeOptions = null;
    System.Threading.CancellationToken cancelationToken = new System.Threading.CancellationToken();
    blobContainer.CreateIfNotExists(publicAccessType, null,encryptionScopeOptions,cancelationToken);


    It creates the blob if it does not exist.
  • WV-08081158-0 Profile Picture
    7 on at
    D365FO and .net dll
    Hi, were you able to solve this?

    I do have exact same problem, the compiler fails on the character between Dictionary and 2 when declaring from X++.
    IDictionary`2
     
    I did try:
           System.Collections.Generic.IDictionary`2<System.String, System.String> metadata =
             new System.Collections.Generic.IDictionary`2<System.String, System.String>();
     
            var metadata = new System.Collections.Generic.IDictionary`2<System.String, System.String>();
     
    Both times it fails on the ` character before the 2.
     
    I'll also try the solution by Gerhard, just passing null for the IDictionary`2 , compiler seems to like that.

    That does indeed work, thanks Gerhard. Also when using AFS instead of Blob.
  • tdgscorpion Profile Picture
    107 on at
    D365FO and .net dll
    Tnak you all for the responses. I wrote all the logic in C# library and used it in X++
  • Verified answer
    Martin Dráb Profile Picture
    236,503 Most Valuable Professional on at
    D365FO and .net dll
    @WV-08081158-0 Please create a new thread for your question, because this one was about a problem CreateIfNotExists(). In short, your code indeed isn't valid X++ and will never compile. You should either avoid generic types in X++ (typically by doing so in a C# library), you'll need to instantiate the object via reflection or you can try the limited (and not really supported) capability for generic types in X++ using the C# syntax (<>).
  • WV-08081158-0 Profile Picture
    7 on at
    D365FO and .net dll
     
    as I did explain in my post. I was able to solve it the same way as Gerhard. So no question and no new thread ;-).
     
    Following code does work:
            ShareFileClient fileClient = new Azure.Storage.Files.Shares.ShareFileClient(connectionString, afsFileShareName, filePathAndName);
            ShareFileHttpHeaders httpHeaders = new Azure.Storage.Files.Shares.Models.ShareFileHttpHeaders();
            FileSmbProperties fileSmbProperties = new Azure.Storage.Files.Shares.Models.FileSmbProperties();
            System.String   filePermission = '';
            ShareFileRequestConditions shareFileRequestConditions = new Azure.Storage.Files.Shares.Models.ShareFileRequestConditions();
            System.Threading.CancellationToken cancellationToken = new System.Threading.CancellationToken();
            fileClient.Create(_stream.Length, httpHeaders, null, fileSmbProperties, filePermission, shareFileRequestConditions, cancellationToken);
           
            ShareFileUploadOptions shareFileUploadOptions = new Azure.Storage.Files.Shares.Models.ShareFileUploadOptions();
            fileClient.Upload(_stream, shareFileUploadOptions, cancellationToken);
           
     
    grtz
    Wim

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

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Abhilash Warrier – Community Spotlight

We are honored to recognize Abhilash Warrier as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
CA Neeraj Kumar Profile Picture

CA Neeraj Kumar 1,882

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 794 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 525 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans