通过Azure Function流式传输Blob内容:HttpResponseMessage被序列化而非传输内容
问题原因与解决方案
你遇到的问题是Azure Function运行模型的差异导致的:
问题根源
如果你的Azure Function使用隔离进程模型(.NET 5及以上版本默认采用此模型),直接返回HttpResponseMessage对象会被当作普通CLR对象进行JSON序列化,而非转换成实际的HTTP响应内容。只有进程内模型(.NET Framework/.NET Core 3.1)才支持直接返回HttpResponseMessage构建响应。
解决方案
情况1:使用隔离进程模型(推荐)
改用HttpRequestData.CreateResponse()创建响应对象,将Blob流直接复制到响应体中,实现流式传输:
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = route)] HttpRequestData req) { var blobServiceClient = new BlobServiceClient(CONNECTION_STRING); var container = blobServiceClient.GetBlobContainerClient(CONTAINER_NAME); var blob = container.GetBlobClient(BLOB_NAME); var stream = await blob.OpenReadAsync(); var response = req.CreateResponse(HttpStatusCode.OK); response.Headers.Add("Content-Type", "application/octet-stream"); response.Headers.Add("Content-Disposition", $"attachment; filename=\"{blob.Name}\""); await stream.CopyToAsync(response.Body); await response.Body.FlushAsync(); return response; }
情况2:使用进程内模型
可以直接返回IActionResult类型的FileStreamResult,贴合ASP.NET Core响应模式的同时保证流式传输:
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = route)] HttpRequest req) { var blobServiceClient = new BlobServiceClient(CONNECTION_STRING); var container = blobServiceClient.GetBlobContainerClient(CONTAINER_NAME); var blob = container.GetBlobClient(BLOB_NAME); var stream = await blob.OpenReadAsync(); return new FileStreamResult(stream, "application/octet-stream") { FileDownloadName = blob.Name }; }
关键说明
两种方案都能实现流式传输,CopyToAsync和FileStreamResult都会逐块读取Blob内容并发送给客户端,不会将整个Blob加载到内存中,符合你的需求。
内容的提问来源于stack exchange,提问作者awj
相关产品推荐
相关产品推荐

