Create file on azure storage in Business Central

2»

Answers

  • Abdullah_ZafarAbdullah_Zafar Member Posts: 4
    ftornero wrote: »
    Hello @Rahila,

    You can add this code to the previous one:
        procedure WriteRange(FileName: Text; TempBlob: Record TempBlob temporary)
        var
            requestMethod: Text;
            request: HttpRequestMessage;
            RequestHeader: HttpHeaders;
            hhtpres: HttpResponseMessage;
            canonicalizedResource: Text;
            canonicalizedHeaders: Text;
            urlPath: Text;
            client: HttpClient;
            content: HttpContent;
            ContentHeaders: HttpHeaders;
            test: Boolean;
            authorizationHeader: Text;
            stringToSign: Text;
            msVersion: Text;
            cha: Text[1];
            contenttype: Text;
            contentLength: Integer;
            res: Text;
            keyss: Text;
            dateInRfc1123Format: Text;  
            EncryptionManagement: Codeunit "Encryption Management";        
            uri: Text;
            Range: Text;
            InStr: InStream;
    
        begin
            if not TempBlob.Blob.HasValue() then
                exit;
    
            cha[1] := 10;
            msVersion := '2015-02-21';
            keyss := GetAccountAccessKey();
            dateInRfc1123Format := GetUTCDateTimeText(); // <------------ Changed
            requestMethod := 'PUT';
    
            urlPath := GetAccountSharedRessource() + '/lables/' + FileName + '?comp=range';
    
            CanonicalizedResource := ConvertStr(StrSubstNo('/%1/%2', GetAccountName(), urlPath), '?=', cha + ':');
    
            TempBlob.Blob.CreateInStream(InStr, TextEncoding::UTF8);
            content.WriteFrom(InStr);
            ContentLength := TempBlob.Blob.Length;
    
            ContentHeaders.Clear();
            content.GetHeaders(ContentHeaders);
            ContentHeaders.Add('Content-Length', Format(ContentLength, 0, 9));
            ContentHeaders.Remove('Content-Type');
            request.Content := content;
    
            Range := 'bytes=0-' + Format(contentLength - 1, 0, 9);
    
            canonicalizedHeaders := 'x-ms-date:' + dateInRfc1123Format + Format(cha) +
                                    'x-ms-range:' + Range + Format(cha) +
                                    'x-ms-version:' + msVersion + Format(cha) +
                                    'x-ms-write:' + 'update';
    
            stringToSign := (requestMethod + Format(cha) +
                             Format(cha) +
                             Format(cha) +
                             Format(contentLength, 0, 9) + Format(cha) +
                             Format(cha) +
                             Format(cha) +
                             Format(cha) +
                             Format(cha) +
                             Format(cha) +
                             Format(cha) +
                             Format(cha) +
                             Format(cha) +
                             canonicalizedHeaders + Format(cha) + // <------------ Changed
                             canonicalizedResource);
    
            authorizationHeader := 'SharedKey ' + GetAccountName() + ':' + EncryptionManagement.GenerateBase64KeyedHashAsBase64String(stringToSign, keyss, 2);
            uri := StrSubstNo('https://%1.file.core.windows.net/%2', GetAccountName(), urlPath);
            request.SetRequestUri(uri);
            request.Method := requestMethod;
            RequestHeader.Clear();
            request.GetHeaders(RequestHeader);
            RequestHeader.Add('Authorization', authorizationHeader);
            RequestHeader.Add('x-ms-date', dateInRfc1123Format);
            RequestHeader.Add('x-ms-range', Range);
            RequestHeader.Add('x-ms-version', msVersion);
            RequestHeader.Add('x-ms-write', 'update');
    
            client.Send(request, hhtpres);
            if not hhtpres.IsSuccessStatusCode then
                Error(hhtpres.ReasonPhrase)
            else
                Message(hhtpres.ReasonPhrase);
        end;
    
        procedure WriteText2File(FileName: Text; qText: Text)
        var
            OutStr: OutStream;
            TempBlob: Record TempBlob temporary;
        begin
            TempBlob.Blob.CreateOutStream(OutStr, TextEncoding::UTF8);
            OutStr.WriteText(qText);
            WriteRange(FileName, TempBlob);
        end;
    

    And call the code whit something like this:
    FileName := 'AzureSharedFile.txt';
    CreateFileNew(FileName);
    WriteText2File(FileName, 'This is a test !!!!');
    

    Regards

    Hi @ftornero I have tried your way and it works fine, but when I tried to write in a file that is not created by your code(means uploaded/created manually) then it's showing an exception "The range specified is invalid for the current size of the resource."
    I have looked into this exception and found that when we create/upload a file manually then its length is fixed which is not changeable.
    https://github.com/Azure/azure-sdk-for-java/issues/14961
    Do you have a workaround for this, because my requirements are a bit different, my user/client will create the file and I have to write/update in that file.
    Best Regards
    Abdullah
  • ftorneroftornero Member Posts: 522
    Hello @Abdullah_Zafar,

    I don't test this issue but maybe the solution would be to read the file, delete it and create a new one with the same name and the correct content.

    Regards.
  • Abdullah_ZafarAbdullah_Zafar Member Posts: 4
    ftornero wrote: »
    Hello @Abdullah_Zafar,

    I don't test this issue but maybe the solution would be to read the file, delete it and create a new one with the same name and the correct content.

    Regards.

    Thanks, @ftornero,
    I have tried different methods,
    1st is: If I upload the file with a size greater than 1kb then it allows us to write,
    2nd: The approach you have followed, first create the file, and then it allows us to write in it, most probably(not sure) due to this header value
    RequestHeader.Add('x-ms-content-length', '1024');
    
    .
    Regards.
Sign In or Register to comment.