MVC Asp.net zip文件下载
本文关键字:文件下载 zip net Asp MVC | 更新日期: 2023-09-27 18:23:47
我在MVC项目中有一些代码,可以创建一个zip文件并将其发送到浏览器。当我在浏览器中手动输入URL时,一切都正常,但如果我点击页面中的链接进行下载,我会得到一个不同大小的文件,Windows无法打开它。
因此,如果我手动输入这样的内容:http://localhost/fms-ui/File/DownloadZipFile/?id=10&filename=DST-2015-114_04_04_04
我得到了一个167字节的zip文件,它打开得很好。
如果我点击页面中的链接,我会得到一个180字节的文件,Windows会说该文件已损坏。匈奴?
我的一个规定是我不能使用外部图书馆。由于政治原因,我必须使用.Net Framework 4.5提供的库(静态ZipFile类)。
代码:
public FileContentResult DownloadZipFile(int id, string filename)
{
/*
* 1 - get fileset info
* 2 - get temp file name
* 3 - create zip file under temp name
* 4- return file
*/
QuesterTangent.Wayside.FileServices.FileSet sInfo = new QuesterTangent.Wayside.FileServices.FileSet(id);
string path = Path.Combine(sInfo.BasePath);
string tempPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".zip");
ZipFile.CreateFromDirectory(path, tempPath);
byte[] fileBytes = System.IO.File.ReadAllBytes(tempPath);
//System.IO.File.Delete(tempPath); Commented so I can compare the files
filename = filename + ".zip";
var cd = new System.Net.Mime.ContentDisposition
{
FileName = filename,
Inline = false,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(fileBytes, "application/zip");
}
我已经尝试过使用和不使用AppendHeader以及各种contentType,但它似乎不会影响结果。
这是调用控制器的JavaScript(我继承了这段代码,但它适用于其他事情)。
function GetFile(url) {
//spin a wheel for friendly buffering time
var buffer = $('.MiddleRightDiv').spinBuffer();
$.ajax({
url: url,
type: "POST",
cache: false,
async: true,
data: {},
success: function (response, status, xhr) {
// check for a filename
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;='n]*=((['"]).*?'2|[^;'n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([response], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location = downloadUrl;
}
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
},
complete: function (result) {
if (typeof $('.MiddleRightDiv').spinBuffer !== 'undefined' && $.isFunction($('.MiddleRightDiv').spinBuffer)) {
$('.MiddleRightDiv').spinBuffer("destroy");
}
}
});
任何投入都会有很大帮助。我看过其他类似的帖子,但似乎没有一个能解决我的核心问题。
谢谢,
dinsdale
jQuery.ajax无法正确读取字节流(请查看SO中的许多主题),因此我们必须使用旧的、好的XMLHttpRequest。以下是重构后的函数,用于处理Blob。当saveAs(blob,filename)是草稿时,用其他浏览器的回退扩展了它。
function GetFile(url) {
if (window.navigator.msSaveBlob) {
var req = new XMLHttpRequest();
req.open('GET', url);
req.responseType = 'arraybuffer';
req.onload = function (e) {
if (req.response) {
var filename = 'archive.zip';
var disposition = req.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;='n]*=((['"]).*?'2|[^;'n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = req.getResponseHeader('Content-Type');
var blob = new Blob([req.response], { type: type ? type : 'application/octet' });
window.navigator.msSaveBlob(blob, filename);
} else {
throw 'Empty or invalid response';
}
}
req.send();
} else {
//fallback for browsers without blob saver
throw 'Not implemented';
}
}