Partilhar via


Utilizar a API Web para carregar ficheiros para o Armazenamento de Blobs do Azure

Este guia demonstra como implementar a API de Ficheiros do Azure. Estes passos permitem que os utilizadores ou visitantes do seu site vejam, editem, criem e eliminem anexos armazenados no Azure.

Nota

  • Tamanho de Ficheiro do Azure de até 10 GB é suportado.
  • Poderá alterar os nomes de coluna ou utilizar uma tabela diferente, ao mesmo tempo que segue os passos neste exemplo.
  • Essas APIs só funcionam para registros já criados. Os anexos carregados através destas APIs serão associados a esse registo.
  • Estas APIs efetuarão várias atualizações na entidade de nota (Anotação) à medida que os ficheiros são carregados em segmentos.

Pré-requisitos

Este passo a passo depende de uma tabela personalizada chamada Teste de Ficheiros. Pode criar uma tabela personalizada com o mesmo nome ou optar por utilizar outra tabela. Obtenha mais informações sobre como criar uma tabela personalizada em Criar e editar tabelas utilizando o Power Apps.

Passo 1: Criar definições do site

Antes de poder utilizar a API de Ficheiros do Azure, tem de ativar as definições de site necessárias com a aplicação Gestão do Portal. As definições do site dependem da tabela que pretende utilizar quando interage com a API de Ficheiros do Azure.

  1. Abra a aplicação Gestão do Portal.

  2. No painel esquerdo da aplicação Gestão do Portal, selecione Definições do Site.

  3. Selecione Novo.

  4. Para o Nome, introduza Site/FileManagement/EnableWebAPI.

  5. Na lista do Site, selecione o seu registo do site.

  6. Para o Valor, introduza verdadeiro.

  7. Selecione Guardar e Fechar.

  8. Adicione as seguintes definições de site:

    Nome de definição do site DefaultValue Description Obrigatório
    Site/FileManagement/EnableWebAPI Ativa a API Web de gestão de ficheiros Sim
    Site/FileManagement/BlobStorageAccountName Nome da Conta de Armazenamento Sim
    Site/FileManagement/BlobStorageContainerName Nome do Contentor Sim
    Site/FileManagement/SupportedFileType Valores separados por vírgulas dos tipos de ficheiro. Por exemplo: .jpeg,.jpg Sim
    Site/FileManagement/SupportedMimeType ; tipos de MIME separados Sim
    Site/FileManagement/MaxFileSize 1048576 (1 GB) Tamanho máximo de ficheiro em KB Não
    Site/FileManagement/DownloadViaSASUri True (ativado por predefinição) Para decidir se pretende utilizar o URI SAS para transferir o ficheiro Não
    Site/FileManagement/DownloadSASUriExpiryTimeSpan 00:10:00 (10 minutos) Período máximo de expiração para URI SAS (necessário se 7 for true) Não
    Site/FileManagement/DownloadChunkSizeInKB 4096 (4 MB) Para decidir o tamanho do segmento a transferir (necessário se 7 for false) Não
  9. Adicione estas definições de site adicionais para ativar a API Web para anotações (notas):

    Nome de definição do site valor
    Webapi/anotação/ativado verdadeiro
    Webapi/anotação/campos *

Passo 2: Configurar permissões

Terá de configurar permissões para que os utilizadores possam utilizar a caraterística API de Ficheiros do Azure. Neste exemplo, precisa de configurar ou de criar uma nova função da Web que utilize a API. De seguida, adicione as permissões de tabela para as tabelas Teste de Ficheiros e Nota e associe as permissões de tabela à função da Web. Por fim, atribui a função da Web aos utilizadores para permitir que utilizem a API.

Nota

A API segue as permissões de tabela do contexto da função da Web do utilizador autenticado ou da função da Web anónima. Considere se os utilizadores já têm uma função da Web que tem acesso às tabelas específicas no seu site requeridas pela API. Não precisa de criar funções da Web adicionais apenas para usar a API.

Criar uma função da Web

Se não tiver uma função da Web com permissões para a tabela necessária, utilize os passos seguintes para criar uma função da Web e atribuir permissões de tabela.

  1. Abra a aplicação Gestão do Portal.

  2. No painel esquerdo, na secção Segurança, selecione Funções da Web.

  3. Selecione Novo.

  4. Para o Nome, introduza Utilizador da API de Ficheiros do Azure ou qualquer nome que melhor reflita a função do utilizador que aceda a esta funcionalidade.

  5. Na lista do Site, selecione o seu registo do site.

  6. Selecione Guardar.

Criar permissões de tabela

  1. Abra o Estúdio de design do Power Pages.

  2. Selecione a área de trabalho Segurança.

  3. Na secção Proteger, selecione Permissões de tabela.

  4. Selecione Nova permissão

  5. Para o Nome, introduza Permissão da Tabela Teste de Ficheiros.

  6. Na lista Nome da Tabela, selecione Teste de Ficheiros (cr463_filetest).

  7. Na lista Tipo de Acesso, selecione Acesso global.

  8. Selecione os privilégios Ler e Anexar a.

  9. Selecione + Adicionar funções e selecione a função da Web criada anteriormente.

  10. Selecione Guardar.

  11. Siga passos semelhantes para criar mais uma permissão para a tabela Nota (anotação) com os privilégios Escrever, Ler, Criar, Anexar e adicionar a mesma função da Web.

Adicionar contactos à função da Web

  1. Abra a aplicação Gestão do Portal.

  2. No painel esquerdo, na secção Segurança, selecione Contactos.

  3. Selecione um contacto que pretende utilizar neste exemplo para a API.

Nota

Este contacto é a conta de utilizador utilizada neste exemplo para testar a API. Certifique-se de que seleciona o contacto correto no seu portal.

  1. Selecione Relacionadas>Funções Web. Verifique se está a utilizar o formulário Contato do Portal. Se usar a Aplicação Power Pages Management, a subgrelha Funções da Web estará localizada na parte inferior do separador Geral.

  2. Selecione Adicionar função Web existente.

  3. Selecione a função de Utilizador da API de Ficheiros do Azure que criou anteriormente.

  4. Selecione Adicionar.

  5. Selecione Guardar e Fechar.

Adicionar permissões baseadas em funções para a aplicação Microsoft Entra

  1. Inicie sessão no Azure onde a conta de armazenamento foi criada.

  2. Aceda ao grupo de recursos, que contém a conta de armazenamento.

  3. Selecione Controlo de acesso (IAM)>Adicionar>Adicionar atribuição de função.

  4. Selecione a função Leitor e, em seguida, selecione Seguinte.

  5. Selecione Utilizador, grupo ou principal de serviço e, em seguida, selecione + Selecionar membros.

  6. No painel do lado direito, escolha a Aplicação empresarial do portal ao pesquisar o nome do site e, em seguida, selecione Selecionar. O nome da aplicação está no seguinte formato:

    Portals-<site name>

  7. Selecione Rever + atribuir>Rever + atribuir.

  8. Aceda à conta de armazenamento e, em seguida, selecione Controlo de Acesso (IAM)>Adicionar>Adicionar atribuição de função.

  9. Selecione a função Contribuidor de Dados de Blobs de Armazenamento e, em seguida, selecione Seguinte.

  10. Selecione Utilizador, grupo ou principal de serviço e, em seguida, selecione + Selecionar membros.

  11. No painel do lado direito, selecione a Aplicação empresarial do portal ao pesquisar o nome do site e, em seguida, selecione Selecionar.

  12. Selecione Rever + atribuir>Rever + atribuir.

Passo 3: Criar uma página Web

Agora que ativou a API de Ficheiros do Azure e configurou as permissões de utilizador, crie uma página Web com uma lista de entidades para a tabela Teste de Ficheiros.

  1. Abra o Estúdio de design do Power Pages.

  2. Na área de trabalho Páginas, selecione + Página e selecione Outras formas de adicionar uma página.

  3. Na caixa de diálogo Adicionar uma página, para o Nome da página, introduza Página de Teste de Ficheiros e selecione Iniciar em branco.

  4. Selecione Adicionar.

  5. Selecione Lista e, em seguida, adicione uma nova lista ou escolha uma lista existente para a tabela Teste de Ficheiros.

    Crie uma página para anexos com o código de amostra a seguir para ver, editar, criar e eliminar registos.

  6. Abra o Estúdio de design do Power Pages.

  7. Na área de trabalho Páginas, selecione + Página e selecione Outras formas de adicionar uma página.

  8. Na caixa de diálogo Adicionar uma página, para o Nome da página, introduza Anexos e selecione Iniciar em branco.

  9. Selecione Adicionar.

  10. Selecione a opção Editar código no canto superior direito.

  11. Selecione Abrir o Visual Studio Code.

  12. Copie o seguinte fragmento de código de amostra e cole-o entre as etiquetas <div></div> da secção de página.

    <style>
    .containerforfile
    {
        display:flex;
        margin-bottom:30px; 
    }
    .btn-for-file
    {
        margin-right:10px;
    }
    .file-name
    {
        padding-top:6px;
    }
    .fileinput
    {
        margin-right:10px;
    }
    .container-progress
    {   
         width: 70%;
         max-width: 400px;  
         margin-top: 10px;   
         position: relative;
    } 
    .parent-progress
    {    
        width: 100%;    
        background-color: #2f5fef;    
        height: 30px;    
        margin-top: 25px;    
        margin-bottom: 20px;
    } 
    .child-progress
    {    
        width: 0%;    
        background-color: #53b453;    
        height: 100%;
    } 
    .prog 
    {    position: absolute;  
      display: block;   
       right: 0; 
    }
    
    #attachments{
        font-family: Arial, Helvetica, sans-serif;
        border-collapse: collapse;
        width: 100%;
      }
      #attachments td,
      #attachments th {
        border: 1px solid #ddd;
        padding: 8px;
      }
      #attachments tr:nth-child(even) {
        background-color: #f2f2f2;
      }
      #attachments tr:hover {
        background-color: #ddd;
      }
      #attachments th {
        padding-top: 12px;
        padding-bottom: 12px;
        text-align: left;
        background-color: #2f5fef;
        color: white;
      }
    </style>
    
    <script>
    function selectFile()
    {var child = document.getElementsByClassName("child-progress")[0];
                                    var progSpan = document.getElementsByClassName("prog")[0];
                                        child.style.width = 0 + "%";
                                    progSpan.innerHTML = 0 + "%";
        var elementToChooseFile = document.getElementById("fileinput");
        elementToChooseFile.click();
    }
    function chooseFile()
    {
        var elementToChooseFile = document.getElementById("fileinput");
        var filename =elementToChooseFile.files[0].name;
        var elementforfilename = document.getElementById("filename");
        elementforfilename.innerText = filename;
        uploadFileinChunks();
    }
    
    (function(webapi, $){
                    function safeAjax(ajaxOptions) {
                        var deferredAjax = $.Deferred();
    
                        shell.getTokenDeferred().done(function (token) {
                        // add headers for AJAX
                        if (!ajaxOptions.headers) {
                        $.extend(ajaxOptions, {
                            headers: {
                                "__RequestVerificationToken": token
                            }
                        }); 
                        } else {
                        ajaxOptions.headers["__RequestVerificationToken"] = token;
                    }
                    $.ajax(ajaxOptions)
                        .done(function(data, textStatus, jqXHR) {
                            validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve);
                        }).fail(deferredAjax.reject); //AJAX
                }).fail(function () {
                    deferredAjax.rejectWith(this, arguments); // on token failure pass the token AJAX and args
                });
    
                return deferredAjax.promise();  
            }
            webapi.safeAjax = safeAjax;
        })(window.webapi = window.webapi || {}, jQuery)
    
    function getFileName(fileName)
    {
        return fileName.replace(/\.azure\.txt$/, '');
    }
    function downloadFile()
    {
        var entityName = document.getElementById("entity_name").value;
        var entityId = document.getElementById("entity_id").value;
        var url = "/_api/file/download/" + entityName + "(" + entityId + ")/blob/$value";
        window.open(url, "_blank");
    }
    
    function uploadFileinChunks()
    {
        var filesizeelement = document.getElementById("filesize");
        var starttimelement = document.getElementById("starttime");
        starttimelement.innerText = new Date().toLocaleString();
        var endtimeelement = document.getElementById("endtime");
        var entityName = "cr463_filetest";
        var entityId = window.location.search.substring(4);
        var url = "/_api/file/InitializeUpload/" + entityName + "(" + entityId + ")/blob"
        var elementToChooseFile = document.getElementById("fileinput");
        var filename = "";
        if (elementToChooseFile.files.length > 0) {
            filename = elementToChooseFile.files[0].name;
        filesizeelement.innerText = elementToChooseFile.files[0].size / 1048576;
            const encodedFileName = encodeURIComponent(filename);
            filename = encodedFileName;
        }
        if (elementToChooseFile.files.length > 0 && elementToChooseFile.files[0].size > 0)
        {
                const chunkSize = 50*1024 *1024;
                let numberOfBlocks;
                let token;
                if (elementToChooseFile.files[0].size % chunkSize == 0)
                {
                    numberOfBlocks = elementToChooseFile.files[0].size / chunkSize;
                }
                else
                {
                    numberOfBlocks = parseInt(elementToChooseFile.files[0].size / chunkSize, 10) + 1;
                }
                webapi.safeAjax({
                    type: "POST",
                    url: url,//replace this with url 
                    headers: { "x-ms-file-name": elementToChooseFile.files[0].name, "x-ms-file-size": elementToChooseFile.files[0].size },
                    contentType: "application/octet-stream",
                    processData: false,
                    data: {},
                    success: function (response, status, xhr)
                    {
                        token = response;
                        uploadFileChunk(0);
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown)
                    {
                        alert(XMLHttpRequest.responseText);
                    }
                });
    
                function uploadFileChunk(blockno)
                {
                    var fileReader = new FileReader();
    
                    if (blockno < numberOfBlocks)
                    {
                        var end = (blockno * chunkSize + chunkSize) > elementToChooseFile.files[0].size ? blockno * chunkSize + elementToChooseFile.files[0].size % chunkSize : blockno * chunkSize + chunkSize;
                        var content = elementToChooseFile.files[0].slice(blockno * chunkSize, end);
                        fileReader.readAsArrayBuffer(content);
                    }
                    fileReader.onload = function ()
                    {
                        webapi.safeAjax({
                            type: "PUT",
                            url: "/_api/file/UploadBlock/blob?offset=" + (blockno * chunkSize) + "&fileSize=" + elementToChooseFile.files[0].size + "&chunkSize=" + chunkSize + "&token=" + token,
                            headers: { "x-ms-file-name": elementToChooseFile.files[0].name },
                            contentType: "application/octet-stream",
                            processData: false,
                            data: content,
                            success: function (res) {
                                var child = document.getElementsByClassName("child-progress")[0];
                                    var progSpan = document.getElementsByClassName("prog")[0];
                                    var percentComplete = ((parseFloat(end) / parseFloat(elementToChooseFile.files[0].size)) * 100).toFixed(2);
    
                                    child.style.width = percentComplete + "%";
                                    progSpan.innerHTML = percentComplete + "%";
                                    if (percentComplete == 100) {
                                        var table = document.getElementById('attachments');
                                        if(table.hidden)
                                        {
                                        var divForNoAttachment = document.getElementById("no-attachment-found");
                                        divForNoAttachment.hidden = true;
                                        table.hidden = false;
                                        }
                                        var row = document.createElement("tr"); 
                                        row.id = token;
                                        row.innerHTML=`<td><a target="_blank" href="/_api/file/download/annotation(` + token + `)/blob/$value" >` + elementToChooseFile.files[0].name + `</a></td>
                                                <td>`+  new Date().toLocaleString() + `</td>     
                                                <td><button class="btn btn-default" onClick="deleteFile('` + token + `');"><i class="glyphicon glyphicon-trash" aria-hidden="true"></i></button></td>`;
                                        table.firstElementChild.nextElementSibling.appendChild(row);
                                        endtimeelement.innerText = new Date().toLocaleString();
                                    }
                                uploadFileChunk(blockno + 1);
                            },
                            error: function (XMLHttpRequest, textStatus, errorThrown) {
                                alert(XMLHttpRequest.responseText);
                            }
                        });
                    }
                }
        }
        else
        {
        alert("no file chosen");
        }
    }
    
    function loadAllAttachments()
    {
        var fetchXmlQuery = `<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
      <entity name="annotation">
        <attribute name="filename" />
        <attribute name="annotationid" />  
        <attribute name="createdon"/>
        <attribute name="objectid" />
        <attribute name="objecttypecode" />
        <filter type="and">
        <condition attribute="filename" operator="like" value="%.azure.txt" />
        </filter>
        <link-entity name="cr463_filetest" from="cr463_filetestid" to="objectid" link-type="inner" alias="ad">
        <filter type="and">
        <condition attribute="cr463_filetestid" operator="eq" value="{` + window.location.search.substring(4) +`}"/>
    </filter>
    </link-entity>
      </entity>
    </fetch>`;
    
    var req = new XMLHttpRequest();
    
    req.open("GET", "/_api/annotations?fetchXml=" +  
        encodeURIComponent(fetchXmlQuery), true);
    
    req.setRequestHeader("Accept", "application/json");
    
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    
    req.onreadystatechange = function ()
    {
        if (this.readyState === 4)
        {
            this.onreadystatechange = null;
            if (this.status === 200)
            {
                var returned = JSON.parse(this.responseText);
                var results = returned.value;
                var loading = document.getElementById('loading');
                if (results.length == 0)
                {
                    var divForNoAttachment = document.getElementById("no-attachment-found");
                        divForNoAttachment.hidden = false;
                }
                else
                {
                for (var i = 0; i < results.length; i++)
                {
                    var table = document.getElementById('attachments');
                    if(table.hidden)
                    {
                        var divForNoAttachment = document.getElementById("no-attachment-found");
                        divForNoAttachment.hidden = true;
                        table.hidden = false;
                    }
                    var row = document.createElement("tr"); 
    
                    var fileName = results[i]["filename"];
                    fileName = fileName.replace(".azure.txt", "");
                    var createdOn = results[i]["createdon"];
                    var annotationid = results[i]["annotationid"];
                    row.id = annotationid;
                    row.innerHTML=`<td><a target="_blank" href="/_api/file/download/annotation(` + annotationid + `)/blob/$value" >` + fileName + `</a></td>
                    <td>`+  createdOn + `</td>     
                    <td><button class="btn btn-default" onClick="deleteFile('` + annotationid + `');"><i class="glyphicon glyphicon-trash" aria-hidden="true"></i></button></td>`;
                    table.firstElementChild.nextElementSibling.appendChild(row);
                }
                }
                loading.hidden= true;
            }
            else
            {
                alert(this.status);
            }
        }
    };
    req.send();
    }
    
    document.addEventListener("DOMContentLoaded", function(){
        loadAllAttachments();
    });
    function deleteFile(entityId)
    {
        var entityName = "annotation";
        var url = "/_api/file/delete/" + entityName + "(" + entityId + ")/blob/$value";
        webapi.safeAjax({
            url: url,
            type: "DELETE",
            success: function(){
    
                var row = document.getElementById(entityId);     
                row.parentNode.removeChild(row);
                var table = document.getElementById('attachments');
    
                if(table.hidden == false && table.tBodies[0].children.length == 0)
                { 
                var divForNoAttachment = document.getElementById("no-attachment-found");
                    divForNoAttachment.hidden = false;
                    table.hidden = true;
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown)
            {
                alert(XMLHttpRequest.responseText); 
            }
        });
    }
    </script> 
    <div style="margin-left:40px;"> 
    <div class="containerforfile" style="display: flex;"> 
      <input type="file" multiple="true" id="fileinput" onchange="chooseFile()" style="display: none;"> 
      <button type="button" id="button-to-choosefile" onclick="selectFile()" class="btn btn-default btn-for-file">Choose File</button> 
      <div id="filename" class="file-name">No File Selected</div> 
    </div> 
    <br> 
    <div> 
    <label for="filesize" id="file_size_label" class="field-label">FileSize(In MB): </label><div class="filesize" id="filesize"></div> 
    <label for="starttime" id="start_time_label" class="field-label">StartTime:</label><div class="starttime" id="starttime"></div> 
    <label for="endtime" id="end_time_label" class="field-label">EndTime:</label><div class="endtime" id="endtime"></div> 
    </div> 
     <div class="container-progress"> 
         <div class="parent-progress" style="width: 100%;background-color: #c1c1c1;    height: 30px;     margin-top: 25px;    margin-bottom: 20px;">         
            <div class="child-progress" style="width: 0%;    background-color: #53b453;    height: 100%;"></div>    
          </div>            
         <span class="prog">0%</span> 
    </div> 
    <br> 
    <br> 
    <h1>Attachments:</h1> 
    <div id="loading"> Loading Attachments...</div> 
     <div id="no-attachment-found" hidden>No Attachment Found!!</div> 
     <table id="attachments" hidden> 
      <thead> 
        <tr> 
          <th>File</th> 
          <th>Created On</th>       
          <th>Actions</th> 
        </tr> 
      </thead> 
    <tbody> 
    </tbody> 
    </table> 
    </div> 
    
  13. Selecione CTRL+S para guardar o código.

  14. Regresse à Página Teste de Ficheiros, selecione a lista e, em seguida, selecione Editar lista.

  15. Aceda a Ações e, em seguida, ative Editar registo.

  16. Para o Tipo de Destino, selecione Página Web.

  17. Para a Página Web, selecione Anexos.

  18. Para Apresentar etiqueta, introduza Carregar anexos.

  19. Selecione Concluído.

  20. No canto superior direito do estúdio de design, selecione Sincronizar para atualizar o site com as edições de código.

Passo 4: Use a API carregar, transferir e eliminar anexos

Para testar a funcionalidade API Web:

  1. Selecione Pré-visualização e, em seguida, selecione Ambiente de trabalho.

  2. Inicie sessão no seu site com a conta de utilizador que está atribuída à função Utilizador da API de Ficheiros do Azure que criou anteriormente.

  3. Aceda à página Web Página Teste de Ficheiros criado anteriormente.

  4. No lado direito, selecione Carregar Anexos.

  5. Escolha um ficheiro e tente carregá-lo.

  6. Tente transferir e eliminar um ficheiro existente.

Agora que criou uma página Web com uma amostra para carregar, transferir e eliminar anexos, poderá personalizar os formulários e o esquema.

Códigos de erro e mensagens

A tabela a seguir inclui os diferentes códigos de erro e mensagens que poderá encontrar ao usar a API Web para carregar ficheiros para o Azure:

Description Estado HTTP Código de Erro Mensagem de Erro
Nenhum ficheiro é anexado para carregar 400 FU00001 O conteúdo do ficheiro não é especificado
O ID da entidade ou o nome fornecido nos parâmetros não está correto 404 FU00002 O registo não foi encontrado
O utilizador não tem permissão 403 FU00003 Não tem permissões para efetuar esta operação
A extensão de ficheiro fornecida não está configurada 400 FU00004 A extensão de ficheiro não é suportada.
O tipo MIME de ficheiro não é suportado 400 FU00005 O tipo MIME de ficheiro não é suportado
O tamanho do ficheiro é maior que o configurado 400 FU00006 O tamanho do ficheiro é maior que {0} MB
As configurações do Azure estão incorretas 400 FU00007 As configurações do Azure estão incorretas
Nome do ficheiro não fornecido 400 FU00008 O x-ms-file-name do cabeçalho está em falta no pedido
API não ativada 501 FU00009 A webapi do Azure não está ativada para utilização
Não é um ficheiro do Azure válido para atualização/bloqueiodeatualização/eliminação/transferência 400 FU00010 O ficheiro pedido não está disponível para {0}
A restrição de IP está ativada no Azure na conta de armazenamento 403 FU00011 A restrição de IP está ativada
O ficheiro não existe no Azure para transferência 400 FU00012 O ficheiro não existe
O tamanho do segmento é maior que 100 mb 400 FU00013 O tamanho do segmento é maior que 100 mb
Tamanho do ficheiro não fornecido 400 FU00014 Tamanho do ficheiro não fornecido
Os tipos de ficheiro suportados não estão definidos 400 FU00015 A extensão de nome de ficheiro não é suportada
Os tipos de MIME suportados não estão definidos 400 FU00016 O tipo de MIME do ficheiro não é suportado
Mais de 128 mb de ficheiro sem segmentação 400 FU00017 O tamanho do ficheiro é superior a 128 mb
Permissão não fornecida à aplicação Microsoft Entra 403 FU00018 A aplicação Microsoft Entra não tem permissões para efetuar esta operação
O certificado não existe para criar ligação ao Azure 400 FU00019 O certificado não existe
Quando o ID do inquilino, o ID do cliente ou a thumbprint não estão definidos na definição da aplicação 500 FU00020 Erro interno do servidor
O tipo de MIME/extensão de ficheiro não suportado 400 FU00021 Tipo de MIME ou extensão de nome de ficheiro não suportada
O nome da conta ou o nome do contentor não existe ou não foi fornecido 400 FU00022 As configurações do Azure estão incorretas