简体   繁体   English

ASP NET MVC 下载 ZIP 文件

[英]ASP NET MVC download ZIP file

I'm trying to download a ZIP file in ASP NET MVC.我正在尝试在 ASP NET MVC 中下载 ZIP 文件。 I have done in ASP NET Webforms, and it works correcly, but I do the same in MVC and I don't get the same result, I tried the following:我在 ASP NET Webforms 中做过,它工作正常,但我在 MVC 中做同样的事情,但没有得到相同的结果,我尝试了以下操作:

public ActionResult Download()
{
    using (ZipFile zip = new ZipFile())
    {
        zip.AddDirectory(Server.MapPath("~/Directories/hello"));
        zip.Save(Server.MapPath("~/Directories/hello/sample.zip"));
        return File(Server.MapPath("~/Directories/hello/sample.zip"), 
                                   "application/zip", "sample.zip");
    }
}

But I get the binary data in screen, not the downloaded zip file why this is not working in MVC?但是我在屏幕上得到二进制数据,而不是下载的 zip 文件,为什么这在 MVC 中不起作用? 在此处输入图像描述

I have found that this does not work if I do it from a partial class, if I execute the download code from the Index and send the file if it works, why?我发现如果我从部分类中执行此操作不起作用,如果我从索引执行下载代码并发送文件(如果它有效),为什么?

I use this to download files.我用它来下载文件。 In your view:在您看来:

var ext = Path.GetExtension(path);
string contentType = GetMimeType(ext);

using (var stream = fileManager.GetStream(path))
{
    var filename = fileManager.GetFileName(path);
    var response = System.Web.HttpContext.Current.Response;
    TransmitStream(stream, response, path, filename, contentType);
    return new EmptyResult();
}

Where GetMimeType is a method that return known MIME types:其中GetMimeType是返回已知 MIME 类型的方法:

public static string GetMimeType(string extension, string defaultValue = "application/octet-stream")
{
    if (extension == null)
    {
        throw new ArgumentNullException(nameof(extension));
    }

    if (!extension.StartsWith("."))
    {
        extension = "." + extension;
    }

    string mime;
    return _mappings.TryGetValue(extension, out mime) ? mime : defaultValue;
}

With _mappings as:使用_mappings为:

private static readonly IDictionary<string, string> _mappings =
   new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) {
        {".323", "text/h323"},
        {".3g2", "video/3gpp2"},
        {".3gp", "video/3gpp"},
        {".3gp2", "video/3gpp2"},
        {".3gpp", "video/3gpp"},
        {".7z", "application/x-7z-compressed"},

        // Other types...

        {".xwd", "image/x-xwindowdump"},
        {".z", "application/x-compress"},
        {".zip", "application/x-zip-compressed"},
    };

And the TransmitStream :TransmitStream

    public static void TransmitStream(
        Stream stream, HttpResponse response, string fullPath, string outFileName = null, string contentType = null)
    {
        contentType = contentType ?? MimeMapping.GetMimeMapping(fullPath);

        byte[] buffer = new byte[10000];
        try
        {
            var dataToRead = stream.Length;

            response.Clear();
            response.ContentType = contentType;

            if (outFileName != null)
            {
                response.AddHeader("Content-Disposition", "attachment; filename=" + outFileName);
            }

            response.AddHeader("Content-Length", stream.Length.ToString());

            while (dataToRead > 0)
            {
                // Verify that the client is connected.
                if (response.IsClientConnected)
                {
                    // Read the data in buffer.
                    var length = stream.Read(buffer, 0, 10000);

                    // Write the data to the current output stream.
                    response.OutputStream.Write(buffer, 0, length);

                    // Flush the data to the output.
                    response.Flush();

                    buffer = new byte[10000];
                    dataToRead = dataToRead - length;
                }
                else
                {
                    // Prevent infinite loop if user disconnects
                    dataToRead = -1;
                }
            }
        }
        catch (Exception ex)
        {
            throw new ApplicationException(ex.Message);
        }
        finally
        {
            response.Close();
        }
    }

Usually, if you want to download something i suggest you to use ContentResult ,transforming the file you want to download into a Base64 String and transforming it on the frontend using javascript with a Blob通常,如果您想下载一些东西,我建议您使用ContentResult ,将您要下载的文件转换为 Base64 字符串并使用带有 Blob 的 javascript 在前端进行转换

Action行动

public ContentResult Download()
{
   MemoryStream memoryStream = new MemoryStream();
   file.SaveAs(memoryStream);

   byte[] buffer = memoryStream.ToArray();
   string fileAsString = Convert.ToBase64String(buffer);

   return Content(file, "application/zip");
}

front end前端

var blob = new Blob([Base64ToBytes(response)], { type: "application/zip" }); 
var link = document.createElement("a");

document.body.appendChild(link);

link.setAttribute("type", "hidden");
link.href = url.createObjectURL(blob);
link.download = fileName;
link.click();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM