【发布时间】:2016-06-12 13:51:22
【问题描述】:
我正在使用this 解决方案来下载文件、压缩并发送给用户,(Azure blobs)。
这是我迄今为止想出的:
public void DownloadImages(DownloadImagesModel model)
{
if (ModelState.IsValid && model.ImageIDs != null && model.ImageIDs.Count > 0)
{
var currentUser = _claimService.GetCurrentClaimsIdentity(TimeZoneExtensions.GetCurrentDate());
var images = _fileService.GetImages(currentUser.CompanyID, model.ImageIDs).ToList();
if (images != null && images.Count > 0)
{
string imageContainerURL = _fileService.GetImageContainerURL(currentUser.CompanyID) + currentUser.ImageContainerToken;
using (var zipOutputStream = new ZipOutputStream(Response.OutputStream))
{
zipOutputStream.SetLevel(0); // 0 - store only to 9 - means best compression
Response.BufferOutput = false;
Response.AddHeader("Content-Disposition", "attachment; filename=" + "zipFileName.rar");
Response.ContentType = "application/octet-stream";
foreach (var image in images)
{
if (image.ImageLinks != null)
{
List<ImageLinkModel> imageLinks = new List<ImageLinkModel>();
if (model.FormatID == 0)
imageLinks = image.ImageLinks.ToList();
else
imageLinks = image.ImageLinks.Where(m => m.FormatID == model.FormatID).ToList();
if (imageLinks != null && imageLinks.Count > 0)
{
//Every image has multiple blobs for different sizes
foreach (var link in imageLinks)
{
CloudBlockBlob blob = _fileService.GetBlob(imageContainerURL, link.BlobName);
var entry = new ZipEntry(image.ImageName)
{
DateTime = TimeZoneExtensions.GetCurrentDate(),
Size = blob.Properties.Length
};
zipOutputStream.PutNextEntry(entry);
//Download
blob.DownloadToStream(zipOutputStream);
Response.Flush();
if (!Response.IsClientConnected)
{
break;
}
}
}
}
}
zipOutputStream.Finish();
zipOutputStream.Close();
}
Response.End();
}
}
}
当我打开下载的 zip 文件时,我得到:
存档意外结束。
压缩包应该包含三个文件,但只包含一个。大小也是0..
我错过了什么?
编辑 1
命名时需要指定.rar类型吗?
我不需要为流设置位置吗?
我是否正确定位了 Flush、Finish、Close 和 End 函数?
编辑 2
这段代码应该可以工作!?
public ActionResult DownloadImages(DownloadImagesModel model)
{
if (ModelState.IsValid && model.ImageIDs != null && model.ImageIDs.Count > 0)
{
var currentUser = _claimService.GetCurrentClaimsIdentity(TimeZoneExtensions.GetCurrentDate());
var images = _fileService.GetImages(currentUser.CompanyID, model.ImageIDs).ToList();
if (images != null && images.Count > 0)
{
var cloudStorageAccount = new CloudStorageAccount(new StorageCredentials("name", "pw"), true);
var container = cloudStorageAccount.CreateCloudBlobClient().GetContainerReference("images-1");
using (var zipOutputStream = new ZipOutputStream(Response.OutputStream))
{
foreach (var image in images)
{
if (image.ImageLinks != null)
{
List<ImageLinkModel> imageLinks = new List<ImageLinkModel>();
if (model.FormatID == 0)
imageLinks = image.ImageLinks.ToList();
else
imageLinks = image.ImageLinks.Where(m => m.FormatID == model.FormatID).ToList();
if (imageLinks != null && imageLinks.Count > 0)
{
zipOutputStream.SetLevel(0);
var blob = container.GetBlockBlobReference(imageLinks.First().BlobName);
var entry = new ZipEntry(imageLinks.First().BlobName);
zipOutputStream.PutNextEntry(entry);
//Download
blob.DownloadToStream(zipOutputStream);
}
}
}
zipOutputStream.Finish();
zipOutputStream.Close();
}
Response.BufferOutput = false;
Response.AddHeader("Content-Disposition", "attachment; filename=" + "zipFileName.zip");
Response.ContentType = "application/octet-stream";
Response.Flush();
Response.End();
return null;
}
}
return null;
}
【问题讨论】:
-
为什么在阅读第一个 blob 后刷新响应?在读取所有 blob 之后,您不应该这样做吗?
-
这是个好问题。我实际上只是跟随其他人的实施。我将冲洗移动到 .finish 和 close 函数之前,但它仍然给我同样的问题..
-
您可以尝试将
blob.DownloadToStream(zipOutputStream);放在zipOutputStream.PutNextEntry(entry);之前,并在zipOutputStream.Close()之后刷新响应,看看是否有什么不同? -
例外:附加信息:没有打开的条目。尝试下载到流时,(blob.DownloadToStream(zipOutputStream))
-
我以为读入流时,它的位置没有重置为0...它在流的最后一位...您是否尝试将流的位置设置回0(在您尝试读取流之前)?
标签: c# asp.net asp.net-mvc azure