我正在尝试从文件系统中压缩一些文件,然后通过前端的 Ajax 请求返回该文件。
我的文档模型包含有关文件所在位置的所有信息以及名称,因此
document.FullPath
是文件的完全限定名称 (path\filename.extension
)。
我目前遇到错误
内容类型不正确:application/json
我不明白为什么。它不会影响控制器动作。
我的控制器看起来像这样:
[HttpPost]
public IActionResult DownloadMyDocuments(int userId)
{
DocumentViewModel documentViewModel= new();
documentViewModel.MyDocuments = _context.Documents.Where(x => x.UserId.Equals(userId)).ToList();
string contentType = null;
if (documentViewModel.MyDocuments != null)
{
using (var stream = new MemoryStream())
{
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
{
foreach (MyDocument document in documentViewModel.MyDocuments)
{
if (System.IO.File.Exists(document.FullPath))
{
contentType = FileHelper.GetMimeContentType(document.FullPath);
byte[] file = System.IO.File.ReadAllBytes(document.FullPath);
var archiveEntry = archive.CreateEntry(document.FileName, CompressionLevel.Fastest);
using (var zipStream = archiveEntry.Open())
{
zipStream.Write(file, 0, file.Length);
}
}
}
}
stream.Position = 0;
return File(stream.ToArray(), "application/zip", "Documents.zip");
}
}
}
我在前端的请求如下所示:
var UserId = $('#downloadDocsUserId').val();
$.ajax({
url: "@Url.Action("DownloadMyDocuments", "Home")",
type: 'POST',
dataType: "JSON",
data: UserId,
processData: true,
dataType: "application/zip",
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log("success", data);
},
error: function (data) {
console.log("error", data);
}
});
DataType 用于告诉 jQuery 它期望从服务器接收的数据类型,而不是指定发送到服务器的数据类型。对于文件下载,实际上不需要指定 dataType,因为需要二进制数据(文件),而不是 JSON 或其他数据格式。您可以创建一个Blob对象,指定该对象的MIME类型为“application/zip”,表明它是一个ZIP文件,并使用JavaScript动态创建下载链接。下载完成后,链接元素将从文档中删除。以保持页面清晰度。这是一个示例代码,您可以参考:
<h2>Download My Documents</h2>
<button id="downloadButton">Download </button>
@section scripts {
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script>
$(document).ready(function () {
$("#downloadButton").click(function () {
var userId = 123;
$.ajax({
url: "@Url.Action("DownloadMyDocuments", "Download")" + "?userId=" + userId,
type: 'POST',
xhrFields: {
responseType: 'blob'
},
success: function (data) {
var myCustomBlob = new Blob([data], { type: "application/zip" });
var link = document.createElement('a');
link.href = window.URL.createObjectURL(myCustomBlob);
link.download = "Documents.zip";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
error: function (xhr, status, error) {
console.log("Error:", error);
}
});
});
});
</script>
}
我的控制器:
[HttpPost]
public IActionResult DownloadMyDocuments(int userId)
{
var documents = _context.Documents.Where(x => x.UserId == userId).ToList();
using (var stream = new MemoryStream())
{
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
{
foreach (var document in documents)
{
if (System.IO.File.Exists(document.FullPath))
{
byte[] file = System.IO.File.ReadAllBytes(document.FullPath);
var archiveEntry = archive.CreateEntry(document.FileName, CompressionLevel.Fastest);
using (var zipStream = archiveEntry.Open())
{
zipStream.Write(file, 0, file.Length);
}
}
}
}
stream.Position = 0;
return File(stream.ToArray(), "application/zip", "Documents.zip");
}