Chiamare le operazioni dell'API REST con l'autorizzazione della chiave condivisa

Questo articolo illustra come chiamare un'operazione dell'API REST di Archiviazione di Azure creando una richiesta REST autorizzata usando C#. Dopo aver appreso come chiamare un'operazione API REST per l'Archivio BLOB, è possibile usare passaggi simili per qualsiasi altra operazione REST di Archiviazione di Azure.

Prerequisiti

L'applicazione di esempio elenca i contenitori BLOB per un account di archiviazione. Per provare il codice di questo articolo, è necessario quanto segue:

  • Installare Visual Studio e includere il carico di lavoro di sviluppo di Azure. Questo esempio è stato compilato usando Visual Studio 2019. Se si usa una versione diversa, le indicazioni potrebbero variare leggermente.

  • Una sottoscrizione di Azure. Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare.

  • Un account di archiviazione di uso generico. Se non si ha un account di archiviazione, vedere Create a storage account (Creare un account di archiviazione).

  • L'esempio riportato in questo articolo illustra come elencare i contenitori di un account di archiviazione. Per visualizzare l'output, aggiungere alcuni contenitori BLOB all'account di archiviazione prima di iniziare.

Scaricare l'applicazione di esempio

L'applicazione di esempio è un'applicazione console scritta in C#.

Usare git per scaricare una copia dell'applicazione nell'ambiente di sviluppo.

git clone https://github.com/Azure-Samples/storage-dotnet-rest-api-with-auth.git

Questo comando consente di duplicare il repository nella cartella locale git. Per aprire la soluzione Visual Studio, passare alla cartella storage-dotnet-rest-api-with-auth e aprire StorageRestApiAuth.sln.

Informazioni su REST

Il trasferimento di stato rappresentativo (REST) è un'architettura che consente di interagire con un servizio tramite un protocollo Internet, ad esempio HTTP/HTTPS. REST è indipendente dal software in esecuzione nel server o nel client. L'API REST può essere chiamata da qualsiasi piattaforma che supporta HTTP/HTTPS. È possibile scrivere un'applicazione da eseguire su un computer Mac, Windows o Linux, un tablet o un telefono Android, un iPhone, un iPod o un sito Web e usare la stessa API REST per tutte le piattaforme.

Una chiamata all'API REST è costituita da una richiesta effettuata dal client e da una risposta restituita dal servizio. Nella richiesta si invia un URL con informazioni sull'operazione che si desidera chiamare, sulla risorsa su cui agire, su eventuali parametri di query e intestazioni e a seconda dell'operazione chiamata, un payload di dati. La risposta del servizio include un codice di stato, un set di intestazioni di risposta e, a seconda dell'operazione chiamata, un payload di dati.

Informazioni sull'applicazione di esempio

L'applicazione di esempio restituisce l'elenco dei contenitori in un account di archiviazione. Dopo aver appreso come mettere in relazione le informazioni presenti nella documentazione dell'API REST con il codice effettivo, sarà più facile capire come configurare le altre chiamate REST.

Consultando l'articolo Blob Service REST API (API REST del servizio BLOB) è possibile esaminare l'elenco di tutte le operazioni che possono essere eseguite sulle risorse di archiviazione BLOB. Le librerie client di archiviazione sono wrapper intorno alle API REST, semplificando l'accesso alle risorse di archiviazione senza usare direttamente le API REST. In alcuni casi, tuttavia, potrebbe essere necessario usare l'API REST anziché una libreria client di archiviazione.

Elencare l'operazione contenitori

Questo articolo è incentrato sull'operazione List Containers. Le informazioni seguenti consentono di comprendere alcuni campi nella richiesta e nella risposta.

Metodo della richiesta: GET. Questo verbo è il metodo HTTP che si specifica come proprietà dell'oggetto della richiesta. Altri valori per questo verbo includono HEAD, PUT e DELETE, a seconda dell'API che si sta chiamando.

URI della richiesta: https://myaccount.blob.core.windows.net/?comp=list. L'URI della richiesta viene creato dall'endpoint dell'account di Archivio BLOB https://myaccount.blob.core.windows.net e dalla stringa di risorsa /?comp=list.

Parametri dell'URI: quando si chiama ListContainers è possibile usare parametri di query aggiuntivi, ad esempio timeout per definire il timeout della chiamata (in secondi) e prefix per applicare un filtro.

Un altro parametro utile è maxresults. Con questo parametro, se sono disponibili più contenitori rispetto al valore specificato, il corpo della risposta conterrà un elemento NextMarker che indica il contenitore da cui ripartire nella richiesta successiva. Per usare questa funzionalità, è necessario specificare il valore NextMarker come parametro marker nell'URI della richiesta successiva. Quando si usa questa funzionalità, è analogo al paging dei risultati.

Per usare parametri aggiuntivi, specificarli dopo la stringa di risorsa con il relativo valore, come in questo esempio:

/?comp=list&timeout=60&maxresults=100

Intestazioni della richiesta: questa sezione include l'elenco delle intestazioni obbligatorie e facoltative della richiesta. Le intestazioni obbligatorie sono tre: Authorization, x-ms-date (data e ora UTC della richiesta) e x-ms-version (versione dell'API REST da usare). L'inclusione di x-ms-client-request-id nelle intestazioni è facoltativa. È possibile impostare il valore per questo campo su qualsiasi elemento e viene scritto nei log di analisi dell'archiviazione quando la registrazione è abilitata.

Corpo della richiesta: non esiste alcun corpo della richiesta per ListContainers. Il corpo della richiesta viene usato in tutte le operazioni PUT durante il caricamento di BLOB, incluso SetContainerAccessPolicy. Il corpo della richiesta consente di inviare in un elenco XML di criteri di accesso archiviati da applicare. Per informazioni su questi criteri, vedere l'articolo Uso delle firme di accesso condiviso.

Codice di stato della risposta: indica i codici di stato che è necessario conoscere. In questo esempio, il codice di stato HTTP 200 indica che l'operazione è stata eseguita correttamente. Per un elenco completo di codici di stato HTTP, consultare Status Code Definitions (Definizioni dei codici di stato). Per i codici di errore specifici per le API REST di archiviazione, vedere Common REST API error codes (Codici di errore comuni delle API REST).

intestazioni di risposta: includono Tipo di contenuto; x-ms-request-id, ovvero l'ID richiesta passato; x-ms-version, che indica la versione del servizio BLOB usata; e Data, che è in formato UTC e indica l'ora in cui è stata effettuata la richiesta.

Corpo della risposta: questo campo è una struttura XML che contiene i dati richiesti. In questo esempio la risposta è un elenco di contenitori e delle relative proprietà.

Creazione della richiesta REST

Per la sicurezza durante l'esecuzione nell'ambiente di produzione, usare sempre HTTPS anziché HTTP. Ai fini di questo esercizio, viene usato HTTP in modo da poter visualizzare i dati di richiesta e risposta. Per esaminare le informazioni relative alla richiesta e alla risposta nelle chiamate REST effettive, è possibile scaricare Fiddler o un'applicazione simile. Nella soluzione Visual Studio il nome e la chiave dell'account di archiviazione sono hardcoded nella classe. Il metodo ListContainersAsyncREST passa il nome dell'account di archiviazione e la chiave dell'account di archiviazione ai metodi usati per creare i vari componenti della richiesta REST. In un'applicazione reale, il nome e la chiave dell'account di archiviazione si troveranno in un file di configurazione o in variabili di ambiente oppure verranno recuperati da un'istanza di Azure Key Vault.

Nel progetto di esempio il codice per la creazione dell'intestazione Authorization si trova in una classe separata. L'idea è che si potrebbe prendere l'intera classe e aggiungerla alla propria soluzione e usarla "così come è". Il codice dell'intestazione dell'autorizzazione è utilizzabile per la maggior parte delle chiamate all'API REST in Archiviazione di Azure.

Per compilare la richiesta, ovvero un oggetto HttpRequestMessage, passare a ListContainersAsyncREST in Program.cs. e seguire questa procedura:

  • Creare l'URI da usare per la chiamata al servizio.
  • Creare l'oggetto HttpRequestMessage e impostare il payload. Per ListContainersAsyncREST il payload è null perché non viene passato alcun elemento.
  • Aggiungere le intestazioni x-ms-date e x-ms-version della richiesta.
  • Ottenere l'intestazione dell'autorizzazione e aggiungerla.

Alcune informazioni di base che è necessario conoscere:

  • Per ListContainers, il metodo è GET. Questo valore viene impostato quando si crea l'istanza della richiesta.
  • La risorsa è la parte di query dell'URI che indica quale API viene chiamata. Il valore della risorsa è pertanto /?comp=list. Come indicato in precedenza, la risorsa è riportata nella pagina della documentazione di riferimento che contiene le informazioni relative all'API ListContainers.
  • L'URI viene creato definendo l'endpoint del servizio BLOB per l'account di archiviazione e concatenando la risorsa. Il valore dell'URI della richiesta è quindi http://contosorest.blob.core.windows.net/?comp=list.
  • Per ListContainers, requestBody è null e non vi sono altre intestazioni.

API diverse potrebbero avere altri parametri da passare, ad esempio ifMatch. che può ad esempio essere usato per una chiamata a PutBlob. In questo caso, si imposta ifMatch su un eTag e il BLOB viene aggiornato solo se l'eTag specificato corrisponde all'eTag corrente nel BLOB. Se un altro utente ha aggiornato il BLOB dopo il recupero dell'eTag, la modifica non viene sottoposta a override.

Per prima cosa, impostare i valori di uri e requestPayload.

// Construct the URI. It will look like this:
//   https://myaccount.blob.core.windows.net/resource
String uri = string.Format("http://{0}.blob.core.windows.net?comp=list", storageAccountName);

// Provide the appropriate payload, in this case null.
//   we're not passing anything in.
Byte[] requestPayload = null;

Creare quindi un'istanza della richiesta impostando il metodo su GET e specificando l'URI.

// Instantiate the request message with a null payload.
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri)
{ Content = (requestPayload == null) ? null : new ByteArrayContent(requestPayload) })
{

Aggiungere le intestazioni della richiesta per x-ms-date e x-ms-version. In questo punto del codice si aggiungono anche le eventuali altre intestazioni della richiesta necessarie per la chiamata. In questo esempio non sono previste intestazioni aggiuntive. Un esempio di API che passa intestazioni aggiuntive è l'operazione Set Container ACL. Questa chiamata API aggiunge un'intestazione denominata "x-ms-blob-public-access" e il valore per il livello di accesso.

// Add the request headers for x-ms-date and x-ms-version.
DateTime now = DateTime.UtcNow;
httpRequestMessage.Headers.Add("x-ms-date", now.ToString("R", CultureInfo.InvariantCulture));
httpRequestMessage.Headers.Add("x-ms-version", "2017-07-29");
// If you need any additional headers, add them here before creating
//   the authorization header.

Chiamare il metodo che crea l'intestazione dell'autorizzazione e aggiungere il risultato alle intestazioni della richiesta. L'intestazione dell'autorizzazione viene creata più avanti nell'articolo. Il nome del metodo è GetAuthorizationHeader, come mostrato in questo frammento di codice:

// Get the authorization header and add it.
httpRequestMessage.Headers.Authorization = AzureStorageAuthenticationHelper.GetAuthorizationHeader(
    storageAccountName, storageAccountKey, now, httpRequestMessage);

A questo punto, httpRequestMessage contiene la richiesta REST completa delle intestazioni di autorizzazione.

Inviare la richiesta

Dopo aver creato la richiesta, è possibile chiamare il metodo SendAsync per inviarla ad Archiviazione di Azure. Verificare che il valore del codice di stato della risposta sia 200, vale a dire che l'operazione sia riuscita. Analizzare quindi la risposta. In questo caso, si ottiene un elenco XML di contenitori. A questo punto può essere utile esaminare il codice per chiamare il metodo GetRESTRequest per creare la richiesta, eseguire la richiesta e quindi analizzare la risposta per l'elenco di contenitori.

    // Send the request.
    using (HttpResponseMessage httpResponseMessage =
      await new HttpClient().SendAsync(httpRequestMessage, cancellationToken))
    {
        // If successful (status code = 200),
        //   parse the XML response for the container names.
        if (httpResponseMessage.StatusCode == HttpStatusCode.OK)
        {
            String xmlString = await httpResponseMessage.Content.ReadAsStringAsync();
            XElement x = XElement.Parse(xmlString);
            foreach (XElement container in x.Element("Containers").Elements("Container"))
            {
                Console.WriteLine("Container name = {0}", container.Element("Name").Value);
            }
        }
    }
}

Se si usa uno sniffer di rete come Fiddler quando si esegue la chiamata a SendAsync, è possibile visualizzare le informazioni della richiesta e della risposta, Vediamo. Il nome dell'account di archiviazione è contosorest.

Richiesta:

GET /?comp=list HTTP/1.1

Intestazioni della richiesta:

x-ms-date: Thu, 16 Nov 2017 23:34:04 GMT
x-ms-version: 2014-02-14
Authorization: SharedKey contosorest:1dVlYJWWJAOSHTCPGiwdX1rOS8B4fenYP/VrU0LfzQk=
Host: contosorest.blob.core.windows.net
Connection: Keep-Alive

Codice di stato e intestazioni della risposta restituiti dopo l'esecuzione:

HTTP/1.1 200 OK
Content-Type: application/xml
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 3e889876-001e-0039-6a3a-5f4396000000
x-ms-version: 2017-07-29
Date: Fri, 17 Nov 2017 00:23:42 GMT
Content-Length: 1511

Corpo della risposta (XML): per l'operazione List Containers viene visualizzato l'elenco dei contenitori e le relative proprietà.

<?xml version="1.0" encoding="utf-8"?>
<EnumerationResults
  ServiceEndpoint="http://contosorest.blob.core.windows.net/">
  <Containers>
    <Container>
      <Name>container-1</Name>
      <Properties>
        <Last-Modified>Thu, 16 Mar 2017 22:39:48 GMT</Last-Modified>
        <Etag>"0x8D46CBD5A7C301D"</Etag>
        <LeaseStatus>unlocked</LeaseStatus>
        <LeaseState>available</LeaseState>
      </Properties>
    </Container>
    <Container>
      <Name>container-2</Name>
      <Properties>
        <Last-Modified>Thu, 16 Mar 2017 22:40:50 GMT</Last-Modified>
        <Etag>"0x8D46CBD7F49E9BD"</Etag>
        <LeaseStatus>unlocked</LeaseStatus>
        <LeaseState>available</LeaseState>
      </Properties>
    </Container>
    <Container>
      <Name>container-3</Name>
      <Properties>
        <Last-Modified>Thu, 16 Mar 2017 22:41:10 GMT</Last-Modified>
        <Etag>"0x8D46CBD8B243D68"</Etag>
        <LeaseStatus>unlocked</LeaseStatus>
        <LeaseState>available</LeaseState>
      </Properties>
    </Container>
    <Container>
      <Name>container-4</Name>
      <Properties>
        <Last-Modified>Thu, 16 Mar 2017 22:41:25 GMT</Last-Modified>
        <Etag>"0x8D46CBD93FED46F"</Etag>
        <LeaseStatus>unlocked</LeaseStatus>
        <LeaseState>available</LeaseState>
        </Properties>
      </Container>
      <Container>
        <Name>container-5</Name>
        <Properties>
          <Last-Modified>Thu, 16 Mar 2017 22:41:39 GMT</Last-Modified>
          <Etag>"0x8D46CBD9C762815"</Etag>
          <LeaseStatus>unlocked</LeaseStatus>
          <LeaseState>available</LeaseState>
        </Properties>
      </Container>
  </Containers>
  <NextMarker />
</EnumerationResults>

Ora che si è appreso come creare la richiesta, chiamare il servizio e analizzare i risultati, è possibile vedere come creare l'intestazione dell'autorizzazione.

Creazione dell'intestazione dell'autorizzazione

Suggerimento

Archiviazione di Azure supporta l'integrazione di Microsoft Entra per BLOB e code. Microsoft Entra ID offre un'esperienza molto più semplice per autorizzare una richiesta ad Archiviazione di Azure. Per altre informazioni sull'uso di Microsoft Entra ID per autorizzare le operazioni REST, vedere Rilasciare autorizzazioni con Microsoft Entra ID. Per una panoramica dell'integrazione di Microsoft Entra con Archiviazione di Azure, vedere Autenticare l'accesso ad Archiviazione di Azure usando Microsoft Entra ID.

Per altre informazioni sui concetti relativi all'autorizzazione, vedere Autorizzare le richieste ad Archiviazione di Azure.

ma ai fini pratici è possibile concentrarsi sulle nozioni fondamentali ed esaminare in dettaglio il codice.

Usare prima di tutto l'autorizzazione con chiave condivisa. L'intestazione dell'autorizzazione ha un formato simile al seguente:

Authorization="SharedKey <storage account name>:<signature>"  

Il campo della firma è un codice HMAC (Hash-based Message Authentication Code) creato dalla richiesta, calcolato con l'algoritmo SHA256 e quindi codificato tramite la codifica Base64.

Questo frammento di codice illustra il formato della stringa della firma con chiave condivisa:

StringToSign = VERB + "\n" +  
               Content-Encoding + "\n" +  
               Content-Language + "\n" +  
               Content-Length + "\n" +  
               Content-MD5 + "\n" +  
               Content-Type + "\n" +  
               Date + "\n" +  
               If-Modified-Since + "\n" +  
               If-Match + "\n" +  
               If-None-Match + "\n" +  
               If-Unmodified-Since + "\n" +  
               Range + "\n" +  
               CanonicalizedHeaders +  
               CanonicalizedResource;  

Per l'archiviazione BLOB, si specificano VERB, md5, Content-Length, CanonicalizedHeaders e CanonicalizedResource. È possibile lasciare vuoti gli altri campi per questo esempio, inserendo tuttavia \n per specificare che sono vuoti.

La canonizzazione è un processo di standardizzazione dei dati con più rappresentazioni possibili. In questo caso, si standardizzano le intestazioni e la risorsa. Le intestazioni canoniche sono le intestazioni che iniziano con "x-ms-". La risorsa canonizzata è l'URI della risorsa, inclusi il nome dell'account di archiviazione e tutti i parametri di query (ad esempio ?comp=list). La risorsa canonica include anche eventuali parametri di query aggiuntivi che potrebbero essere stati aggiunti, ad esempio timeout=60.

Si inizierà con i due campi canonici, perché sono necessari per creare l'intestazione di Autorizzazione.

Intestazioni canoniche

Per creare questo valore, recuperare le intestazioni che iniziano con "x-ms-", ordinarle e quindi formattarle in una singola stringa di istanze [key:value\n] concatenate. Per questo esempio, le intestazioni in forma canonica hanno l'aspetto seguente:

x-ms-date:Fri, 17 Nov 2017 00:44:48 GMT\nx-ms-version:2017-07-29\n

Ecco il codice usato per creare tale output:

private static string GetCanonicalizedHeaders(HttpRequestMessage httpRequestMessage)
{
    var headers = from kvp in httpRequestMessage.Headers
        where kvp.Key.StartsWith("x-ms-", StringComparison.OrdinalIgnoreCase)
        orderby kvp.Key
        select new { Key = kvp.Key.ToLowerInvariant(), kvp.Value };

    StringBuilder headersBuilder = new StringBuilder();

    foreach (var kvp in headers)
    {
        headersBuilder.Append(kvp.Key);
        char separator = ':';

        // Get the value for each header, strip out \r\n if found, then append it with the key.
        foreach (string headerValue in kvp.Value)
        {
            string trimmedValue = headerValue.TrimStart().Replace("\r\n", string.Empty);
            headersBuilder.Append(separator).Append(trimmedValue);

            // Set this to a comma; this will only be used
            // if there are multiple values for one of the headers.
            separator = ',';
        }

        headersBuilder.Append("\n");
    }

    return headersBuilder.ToString();
}

Risorsa canonica

Questa parte della stringa relativa alla firma rappresenta l'account di archiviazione a cui fa riferimento la richiesta. Tenere presente che l'URI della richiesta è http://contosorest.blob.core.windows.net/?comp=list, con il nome dell'account effettivo, in questo caso contosorest. In questo esempio viene restituita la stringa seguente:

/contosorest/\ncomp:list

Se sono presenti parametri di query, questo esempio include anche questi parametri. Di seguito è riportato il codice che gestisce anche altri parametri di query, eventualmente con più valori. Tenere presente che questo codice dovrà funzionare per tutte le API REST. Si vogliono includere tutte le possibilità, anche se il metodo ListContainers non ne ha bisogno.

private static string GetCanonicalizedResource(Uri address, string storageAccountName)
{
    // The absolute path will be "/" because for we're getting a list of containers.
    StringBuilder sb = new StringBuilder("/").Append(storageAccountName).Append(address.AbsolutePath);

    // Address.Query is the resource, such as "?comp=list".
    // This ends up with a NameValueCollection with 1 entry having key=comp, value=list.
    // It will have more entries if you have more query parameters.
    NameValueCollection values = HttpUtility.ParseQueryString(address.Query);

    foreach (var item in values.AllKeys.OrderBy(k => k))
    {
        sb.Append('\n').Append(item.ToLower()).Append(':').Append(values[item]);
    }

    return sb.ToString();
}

Ora che le stringhe in forma canonica sono impostate, si vedrà come creare effettivamente l'intestazione dell'autorizzazione. Per prima cosa, creare una stringa della firma del messaggio nel formato StringToSign illustrato in precedenza in questo articolo. Questo concetto è più semplice da spiegare mostrando il codice con i commenti. Ecco quindi il metodo finale che restituisce l'intestazione dell'autorizzazione:

internal static AuthenticationHeaderValue GetAuthorizationHeader(
    string storageAccountName, string storageAccountKey, DateTime now,
    HttpRequestMessage httpRequestMessage, string ifMatch = "", string md5 = "")
{
    // This is the raw representation of the message signature.
    HttpMethod method = httpRequestMessage.Method;
    String MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n\n\n\n{2}\n\n\n\n{3}{4}",
                method.ToString(),
                (method == HttpMethod.Get || method == HttpMethod.Head) ? String.Empty
                  : httpRequestMessage.Content.Headers.ContentLength.ToString(),
                ifMatch,
                GetCanonicalizedHeaders(httpRequestMessage),
                GetCanonicalizedResource(httpRequestMessage.RequestUri, storageAccountName),
                md5);

    // Now turn it into a byte array.
    byte[] SignatureBytes = Encoding.UTF8.GetBytes(MessageSignature);

    // Create the HMACSHA256 version of the storage key.
    HMACSHA256 SHA256 = new HMACSHA256(Convert.FromBase64String(storageAccountKey));

    // Compute the hash of the SignatureBytes and convert it to a base64 string.
    string signature = Convert.ToBase64String(SHA256.ComputeHash(SignatureBytes));

    // This is the actual header that will be added to the list of request headers.
    AuthenticationHeaderValue authHV = new AuthenticationHeaderValue("SharedKey",
        storageAccountName + ":" + signature);
    return authHV;
}

Quando si esegue questo codice, il valore messageSignature risultante è simile all'esempio seguente:

GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 17 Nov 2017 01:07:37 GMT\nx-ms-version:2017-07-29\n/contosorest/\ncomp:list

Ecco infine il valore per l'intestazione dell'autorizzazione:

SharedKey contosorest:Ms5sfwkA8nqTRw7Uury4MPHqM6Rj2nfgbYNvUKOa67w=

L'intestazione dell'autorizzazione è l'ultima intestazione inserita nelle intestazioni della richiesta prima dell'invio della risposta.

Ciò copre tutto ciò che è necessario sapere per mettere insieme una classe con cui è possibile creare una richiesta per chiamare le API REST di Servizi di archiviazione.

Esempio: List Blobs

Si vedrà ora come modificare il codice per chiamare l'operazione List Blobs per il contenitore container-1. Questo codice è quasi identico al codice per elencare i contenitori, le uniche differenze sono l'URI e il modo in cui si analizza la risposta.

Se si consulta la documentazione di riferimento per ListBlobs, si vedrà che il metodo da usare è GET e il valore di RequestURI è il seguente:

https://myaccount.blob.core.windows.net/container-1?restype=container&comp=list

In ListContainersAsyncREST modificare il codice che imposta l'URI sull'API per ListBlobs. Il nome del contenitore è container-1.

String uri =
    string.Format("http://{0}.blob.core.windows.net/container-1?restype=container&comp=list",
      storageAccountName);

Pertanto, nel punto in cui si gestisce la risposta, modificare il codice in modo da eseguire la ricerca di BLOB e non di contenitori.

foreach (XElement container in x.Element("Blobs").Elements("Blob"))
{
    Console.WriteLine("Blob name = {0}", container.Element("Name").Value);
}

Quando si esegue questo esempio, si ottengono risultati simili ai seguenti:

Intestazioni canoniche:

x-ms-date:Fri, 17 Nov 2017 05:16:48 GMT\nx-ms-version:2017-07-29\n

Risorsa Canonical:

/contosorest/container-1\ncomp:list\nrestype:container

Firma del messaggio:

GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Fri, 17 Nov 2017 05:16:48 GMT
  \nx-ms-version:2017-07-29\n/contosorest/container-1\ncomp:list\nrestype:container

Intestazione autorizzazione:

SharedKey contosorest:uzvWZN1WUIv2LYC6e3En10/7EIQJ5X9KtFQqrZkxi6s=

I valori seguenti sono restituiti da Fiddler:

Richiesta:

GET http://contosorest.blob.core.windows.net/container-1?restype=container&comp=list HTTP/1.1

Intestazioni della richiesta:

x-ms-date: Fri, 17 Nov 2017 05:16:48 GMT
x-ms-version: 2017-07-29
Authorization: SharedKey contosorest:uzvWZN1WUIv2LYC6e3En10/7EIQJ5X9KtFQqrZkxi6s=
Host: contosorest.blob.core.windows.net
Connection: Keep-Alive

Codice di stato e intestazioni della risposta restituiti dopo l'esecuzione:

HTTP/1.1 200 OK
Content-Type: application/xml
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: 7e9316da-001e-0037-4063-5faf9d000000
x-ms-version: 2017-07-29
Date: Fri, 17 Nov 2017 05:20:21 GMT
Content-Length: 1135

Corpo della risposta (XML): questa risposta XML mostra l'elenco di BLOB e le relative proprietà.

<?xml version="1.0" encoding="utf-8"?>
<EnumerationResults
    ServiceEndpoint="http://contosorest.blob.core.windows.net/" ContainerName="container-1">
    <Blobs>
        <Blob>
            <Name>DogInCatTree.png</Name>
            <Properties><Last-Modified>Fri, 17 Nov 2017 01:41:14 GMT</Last-Modified>
            <Etag>0x8D52D5C4A4C96B0</Etag>
            <Content-Length>419416</Content-Length>
            <Content-Type>image/png</Content-Type>
            <Content-Encoding />
            <Content-Language />
            <Content-MD5 />
            <Cache-Control />
            <Content-Disposition />
            <BlobType>BlockBlob</BlobType>
            <LeaseStatus>unlocked</LeaseStatus>
            <LeaseState>available</LeaseState>
            <ServerEncrypted>true</ServerEncrypted>
            </Properties>
        </Blob>
        <Blob>
            <Name>GuyEyeingOreos.png</Name>
            <Properties>
                <Last-Modified>Fri, 17 Nov 2017 01:41:14 GMT</Last-Modified>
                <Etag>0x8D52D5C4A25A6F6</Etag>
                <Content-Length>167464</Content-Length>
                <Content-Type>image/png</Content-Type>
                <Content-Encoding />
                <Content-Language />
                <Content-MD5 />
                <Cache-Control />
                <Content-Disposition />
                <BlobType>BlockBlob</BlobType>
                <LeaseStatus>unlocked</LeaseStatus>
                <LeaseState>available</LeaseState>
                <ServerEncrypted>true</ServerEncrypted>
            </Properties>
            </Blob>
        </Blobs>
    <NextMarker />
</EnumerationResults>

Riepilogo

In questo articolo si è appreso come effettuare una richiesta all'API REST dell'Archivio BLOB. Con la richiesta è possibile recuperare un elenco di contenitori o un elenco di BLOB in un contenitore. Si è appreso come creare la firma di autorizzazione per la chiamata API REST e come usarla nella richiesta REST. Infine, si è appreso come esaminare la risposta.

Passaggi successivi