jquery 如何将包含多个文档的zip文件从ASP.NETMVC控制器返回到Ajax请求?

wmomyfyw  于 5个月前  发布在  jQuery
关注(0)|答案(1)|浏览(66)

我试图从文件系统压缩一些文件,然后通过前端的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);
    }
});

w41d8nur

w41d8nur1#

DataType用于告诉jQuery它期望从服务器接收的数据类型,而不是指定您发送到服务器的数据类型。对于文件下载,实际上不需要指定dataType,因为需要的是二进制数据(文件),而不是JSON或其他数据格式。您可以创建一个Blob对象,指定对象的MIME类型为“application/zip”,表示它是ZIP文件,并使用JavaScript动态创建下载链接。下载完成后,link元素将从文档中删除。以保持页面清晰度。下面是一个示例代码,您可以用作参考:

<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");
     }


当我点击按钮:x1c 0d1x
将下载相应的文件:

相关问题