Загрузите в хранилище Azure Blob с общим ключом доступа

UPD: вот мое реализовано решение этой проблемы

Я пытаюсь загрузить в Azure blob-хранилище через библиотеку Azure.Storage(а не REST API) и аутентифицироваться через общий ключ доступа.

Я видел этот сообщение в блоге, но API изменился со времени публикации, и теперь я не могу получить тот же результат.

Вот что у меня есть:

var blobClient = new CloudBlobClient(new Uri(blobWithSas.BaseUri), new StorageCredentials(blobWithSas.Sas));


// here I receive 404 error
var blob = blobClient.GetBlobReferenceFromServer(new Uri(blobWithSas.AbsoluteUri));

using (var stream = new FileStream(fullFilePath, FileMode.Open))
{
    blob.UploadFromStream(stream);
}

Имея:

blobWithSas.BaseUri= http://127.0.0.1:10000/devstoreaccount1/a6dc9274-6ce1-4095-be6b-e84d1012cb24 (Guid - это имя контейнера, уже существующее, созданное где-то еще.)

blobWithSas.Sas= ?sv=2012-02-12&se=2013-06-23T03%3A04%3A53Z&sr=b&sp=w&sig=NaMqgXRMXDFvLAp8LTskgplAKp%2B9LCZzq8WK9Zo35x8%3D (также выдается в другом месте в коде)

blobWithSas.AbsoluteUri= http://127.0.0.1:10000/devstoreaccount1/a6dc9274-6ce1-4095-be6b-e84d1012cb24/foldername/filename.txt

Blob не существует, я хочу загрузить новый файл и создать blob. У меня есть приложение "Сервер", содержащее ключ доступа к учетной записи Azure Storage. Сервер выдает SAS клиентам и клиентам, загружающим файлы непосредственно в Azure. Таким образом, SAS будет писать только, без чтения, а клиенты будут создавать файлы, где сервер сообщает им (контейнер, имена папок)

Проблема возникает при GetBlobReferenceFromServer - я получаю 404 ошибку от Azure Storage. Да, blob не существует и ссылки нет. Итак, учитывая CloudBlobClient, как я могу загрузить файл в blob?

p.s. Я понимаю, что для этого есть REST API. Но я раньше использовал библиотеку Microsoft.WindowsAzure.Storage и хотел бы, если возможно, избегать службы REST.

Ответ 1

Проблема возникает на GetBlobReferenceFromServer - я получаю ошибку 404 от Azure Storage. Да, blob не существует, и нет Справка. Поэтому, учитывая CloudBlobClient, как я могу загрузить файл в BLOb?

Чтобы работать GetBlobReferenceFromServer, blob должен присутствовать в хранилище blob. Это полезно в сценарии, когда вы знаете, что blob существует в хранилище и хотел бы узнать тип blob - Block Blob или Page Blob.

Если вы хотите создать блок-блок, загрузив файл с локального компьютера, вы можете сделать что-то вроде:

    var blob = new CloudBlockBlob(new Uri(blobWithSas.AbsoluteUri), new StorageCredentials(blobWithSas.Sas));
using (var stream = new FileStream(fullFilePath, FileMode.Open))
{
    blob.UploadFromStream(stream);
}

Приступая к совместной работе с сигнатурой доступа, я написал сообщение в блоге не так давно: http://gauravmantri.com/2013/02/13/revisiting-windows-azure-shared-access-signature/. Вы можете назвать его версией 2 сообщения в блоге Steve:). Я показал примеры загрузки капель с общей подписью доступа с использованием как REST API, так и Storage Client Library 2.0.

Некоторые примеры кода из сообщения в блоге:

Использование библиотеки клиентских хранилищ:

/// <summary>
/// Uploads a blob in a blob container where SAS permission is defined on a blob container using storage client library.
/// </summary>
/// <param name="blobContainerSasUri"></param>
static void UploadBlobWithStorageClientLibrarySasPermissionOnBlobContainer(string blobContainerSasUri)
{
    CloudBlobContainer blobContainer = new CloudBlobContainer(new Uri(blobContainerSasUri));
    CloudBlockBlob blob = blobContainer.GetBlockBlobReference("sample.txt");
    string sampleContent = "This is sample text.";
    using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(sampleContent)))
    {
        blob.UploadFromStream(ms);
    }
}

Использование REST API:

/// <summary>
/// Uploads a blob in a blob container where SAS permission is defined on a blob container using REST API.
/// </summary>
/// <param name="blobContainerSasUri"></param>
static void UploadBlobWithRestAPISasPermissionOnBlobContainer(string blobContainerSasUri)
{
    string blobName = "sample.txt";
    string sampleContent = "This is sample text.";
    int contentLength = Encoding.UTF8.GetByteCount(sampleContent);
    string queryString = (new Uri(blobContainerSasUri)).Query;
    string blobContainerUri = blobContainerSasUri.Split('?')[0];
    string requestUri = string.Format(CultureInfo.InvariantCulture, "{0}/{1}{2}", blobContainerUri, blobName, queryString);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
    request.Method = "PUT";
    request.Headers.Add("x-ms-blob-type", "BlockBlob");
    request.ContentLength = contentLength;
    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
    }
    using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
    {

    }
}

Вы также можете найти это сообщение в блоге полезным: http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/