.NET Core:将Azure存储Blob读取到内存流中会在HttpBaseStream中引发NotSupportedException

.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();

我想从Azure下载一个存储blob,并通过.NET Web应用程序将其流式传输到客户端。blob已正确上载,并且在我的Azure存储帐户中可见

令人惊讶的是,以下代码在HttpBaseStream中引发了一个异常:

    [...] 
    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();
        }
    }