.NET Core:将Azure存储Blob读取到内存流中会在HttpBaseStream中引发NotSupportedException
我想从Azure下载一个存储blob,并通过.NET Web应用程序将其流式传输到客户端。blob已正确上载,并且在我的Azure存储帐户中可见 令人惊讶的是,以下代码在HttpBaseStream中引发了一个异常:.NET Core:将Azure存储Blob读取到内存流中会在HttpBaseStream中引发NotSupportedException,azure,asp.net-core,.net-core,azure-storage-blobs,Azure,Asp.net Core,.net Core,Azure Storage Blobs,我想从Azure下载一个存储blob,并通过.NET Web应用程序将其流式传输到客户端。blob已正确上载,并且在我的Azure存储帐户中可见 令人惊讶的是,以下代码在HttpBaseStream中引发了一个异常: [...] var blobClient = _containerClient.GetBlobClient(Path.Combine(fileName)); var stream = await blobClient.OpenReadAsync();
[...]
var blobClient = _containerClient.GetBlobClient(Path.Combine(fileName));
var stream = await blobClient.OpenReadAsync();
return stream;
->当我进一步返回一个文件(返回文件(stream,MediaTypeNames.Application.Octet);
)时,下载会按预期工作
我尝试将流推送到MemoryStream,但也失败了,出现了相同的异常:
[...]
var blobClient = _containerClient.GetBlobClient(Path.Combine(fileName));
var stream = new MemoryStream();
await blobClient.DownloadToAsync(stream);
return stream
->当我更进一步时,返回文件会导致超时
我怎样才能解决这个问题?为什么我会遇到这个例外-我遵循了微软的官方快速入门指南
以下代码在HttpBaseStream中引发异常
HTTP结果类型似乎正在尝试设置内容长度
标题,并正在读取长度
。这是很自然的事情。但是,处理NotSupportedException
也是很自然的,只是根本不设置内容长度
如果NotSupportedException
仅在调试器中运行时显示,则忽略它
如果异常实际上被抛出到代码中(即导致请求失败),那么您需要遵循此答案的其余部分
首先,创建一个最小的可复制示例,并向.NET团队报告一个bug
为了同时解决这个问题,我建议编写一个流包装器,返回一个已经确定的长度,您可以从Azure blob属性中获得该长度。例如:
public sealed class KnownLengthStreamWrapper : Stream
{
private readonly Stream _stream;
public KnownLengthStreamWrapper(Stream stream, long length)
{
_stream = stream;
Length = length;
}
public override long Length { get; private set; }
... // override all other Stream members and forward to _stream.
}
这应该足以让你的应用程序工作
我试图把这条小溪推进记忆之流
这不起作用,因为您需要在某个点“倒带”内存流,例如:
var stream = new MemoryStream();
await blobClient.DownloadToAsync(stream);
stream.Position = 0;
return stream;
检查我已经发布在git上的所有blob选项的示例,这些选项按预期工作
您使用的SDK版本是什么?Azure blob storage v12(12.8.1)和.NET Core 5.0。
public void DownloadBlob(string path)
{
storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
CloudBlobClient client = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = client.GetContainerReference("images");
CloudBlockBlob blockBlob = container.GetBlockBlobReference(Path.GetFileName(path));
using (MemoryStream ms = new MemoryStream())
{
blockBlob.DownloadToStream(ms);
HttpContext.Current.Response.ContentType = blockBlob.Properties.ContentType.ToString();
HttpContext.Current.Response.AddHeader("Content-Disposition", "Attachment; filename=" + Path.GetFileName(path).ToString());
HttpContext.Current.Response.AddHeader("Content-Length", blockBlob.Properties.Length.ToString());
HttpContext.Current.Response.BinaryWrite(ms.ToArray());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.Close();
}
}