web-dev-qa-db-ja.com

Azure Blob Storageからブラウザーにファイルをダウンロードする方法

すでに利用可能なファイルを一覧表示していますが、ユーザーがサーバーに保存せずにダウンロードできるように、そのファイルをブラウザーに渡す方法を知る必要がありました

ファイルのリストを取得する方法は次のとおりです

var azureConnectionString = CloudConfigurationManager.GetSetting("AzureBackupStorageConnectString");
var containerName = ConfigurationManager.AppSettings["FmAzureBackupStorageContainer"];
if (azureConnectionString == null || containerName == null)
    return null;

CloudStorageAccount backupStorageAccount = CloudStorageAccount.Parse(azureConnectionString);
var backupBlobClient = backupStorageAccount.CreateCloudBlobClient();
var container = backupBlobClient.GetContainerReference(containerName); 
var blobs = container.ListBlobs(useFlatBlobListing: true);
var downloads = blobs.Select(blob => blob.Uri.Segments.Last()).ToList();
25

BlobコンテンツはWebサーバーを介して、ブラウザを介してエンドユーザーにストリーミングされる可能性がありますが、このソリューションはCPUとNICの両方のWebサーバーに負荷をかけます。

別のアプローチは、エンドユーザーに、ダウンロードする目的のBLOBへのuriを提供することです。これは、htmlコンテンツ内でクリックできます。例えばhttps://myaccount.blob.core.windows.net/mycontainer/myblob.ext

これに関する問題は、コンテンツがプライベートな場合です。なぜなら、上記のようなuriは、パブリックBLOBを使用しないと機能しないからです。このために、共有アクセス署名(またはサーバーに保存されたポリシー)を作成できます。これにより、ハッシュにクエリ文字列がuriに追加されます。この新しいuriは、一定の時間(たとえば、10分)の間有効です。

以下に、blobのSASを作成する小さな例を示します。

var sasConstraints = new SharedAccessBlobPolicy();
sasConstraints.SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5);
sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10);
sasConstraints.Permissions = SharedAccessBlobPermissions.Read;

var sasBlobToken = blob.GetSharedAccessSignature(sasConstraints);

return blob.Uri + sasBlobToken;

開始時刻は過去数分に設定されていることに注意してください。これは、クロックドリフトに対処するためです。 完全なチュートリアル このコードサンプルを入手/変更しました。

直接BLOBアクセスを使用することにより、VM/Webロールインスタンス/ Webサイトインスタンスを完全にバイパスし(サーバーの負荷を軽減)、エンドユーザーにBLOBストレージから直接BLOBコンテンツをプルさせます。 Webアプリを使用して、許可、配信するコンテンツの決定などを処理できます。ただし、これにより、Webサーバーを介してストリーミングするのではなく、BLOBリソースに直接リンクできます。

49
David Makogon

ユーザーがファイルをクリックすると、サーバーはこれで応答します

var blob = container.GetBlobReferenceFromServer(option);

var memStream = new MemoryStream();
blob.DownloadToStream(memStream);

Response.ContentType = blob.Properties.ContentType;
Response.AddHeader("Content-Disposition", "Attachment;filename=" + option);
Response.AddHeader("Content-Length", blob.Properties.Length.ToString());
Response.BinaryWrite(memStream.ToArray());

Dhananjay Kumar このソリューションに感謝します

9

ASP.NET(コア)を使用する場合、サーバーにファイルを保存せずにブラウザーにコンテンツをストリーミングでき、IActionResultであるFileStreamResultを使用すると、よりエレガントなソリューションになります。

var stream = await blob.OpenReadAsync();
return File(stream, blob.Properties.ContentType, option);
3
Andy