从HTTP流式传输时损坏文件



我在通过HTTP响应中流式传输文件有问题。无论我做什么,它都会破坏!

背景是我需要发送生成的XLS文件(我正在使用NPOI)。我知道生成的文件很好,因为如果我将其直接保存到磁盘上,我可以打开它,没有问题!但是……当我尝试通过HTTP流式传输该文件时,它会损坏(我尝试了三种不同的方法,如下所示……)。为此,最重要的是,不仅XLS文件损坏了,而且是我加载的所有文件(我尝试过JPG,PNG和TXT文件)。每当我通过http发送它们时,它都会损坏。无论如何,这都是我尝试的:

  1. 我已经尝试手动构建HTTP响应:

    Export export = new Export(header, data); 
    MemoryStream stream = export.GetXLSStream("test"); // This generates a memory stream of the XLS file
    // Writing that stream to a file works! This file opens just fine
    var fs = new FileStream(@"C:export.xls", FileMode.Create, System.IO.FileAccess.Write);
    stream.WriteTo(fs);
    // However, this doesn't!
    Response.ClearContent();
    Response.AddHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
    Response.AddHeader("Content-Disposition", "attachment; filename=export.xls");
    Response.AddHeader("Content-Type", "application/vnd.ms-excel");
    Response.AddHeader("Content-Transfer-Encoding", "binary");
    Response.BinaryWrite(stream.ToArray());
    Response.End();
    return null;
    
  2. 我尝试使用FileStreamResult:

    Export export = new Export(header, data); 
    MemoryStream stream = export.GetXLSStream("test"); // This generates a memory stream of the XLS file
    return File(stream, "application/vnd.ms-excel", "export.xsl");
    
  3. 我尝试使用FileContentResult:

    Export export = new Export(header, data); 
    MemoryStream stream = export.GetXLSStream("test"); // This generates a memory stream of the XLS file
    return File(stream.ToArray(), "application/vnd.ms-excel", "export.xsl");
    
  4. 我尝试使用filepathresult:

    Export export = new Export(header, data); 
    MemoryStream stream = export.GetXLSStream("test"); // This generates a memory stream of the XLS file
    var fs = new FileStream(@"C:export.xls", FileMode.Create, System.IO.FileAccess.Write);
    stream.WriteTo(fs);
    fs.Close();
    return File(@"C:export.xls", "application/vnd.ms-excel", "export.xsl");
    
  5. ,我尝试加载随机文件,例如:

    return File(@"C:test.jpg", "image/jpeg", "test.jpg");
    

进行MD5或CRC检查还向我表明,我通过HTTP获得的文件与原始文件不同(即使它们具有完全相同的字节数)。

这是对我有用的代码:

public MyController : Controller {
    public ActionResult GetFile()
    {
        // ...
        return File(stream, "application/octet-stream", "file.xls");
    }
}

我在 mvc 中使用 npoi 1.2.5,.net 4.0 按以下方式:

我有自定义ActionResult 类带有以下方法:

public override sealed void ExecuteResult(ControllerContext context)
{
    IWorkbook workbook = XlsData.CreateTestWorkbook().Workbook;
    HttpResponseBase response = context.HttpContext.Response;
    response.Clear();
    response.ContentType = "application/vnd.ms-excel";
    response.Headers.Add("content-disposition", "attachment;  filename=Test.xls");
    using (var ms = new MemoryStream())
    {
        workbook.Write(ms);
        ms.WriteTo(response.OutputStream);
    }
    response.End();
}

其中XlsData.CreateTestWorkbook()是一些创建我NPOI示例工作簿的类。

  • 然后在我的控制器方法中,我只返回我的自定义ActionResult

  • 我的控制器方法具有 [httpget] 属性,并从
    中调用客户端带有HTML链接下载按钮。

看起来它是我在控制器根部应用的空间滤波器,以使输出所有一条线。除了HTML响应外,它都不应该应用于任何其他内容,但是我更改了代码,以使其根本不以此为响应。

尝试此方法,对我来说很好

        using (var fileData = new FileStream(filename, FileMode.Create))
        {
            workbook.Write(fileData);
        }
        using (var exportData = new MemoryStream())
        {
            workbook.Write(exportData);
            string saveAsFileName = string.Format("MembershipExport-{0:d}.xls", DateTime.Now).Replace("/", "-");
            Response.ContentType = "application/vnd.ms-excel";
            Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", saveAsFileName));
            Response.Clear();
            Response.BinaryWrite(exportData.GetBuffer());
            Response.End();
        }
MemoryStream outStream = (MemoryStream)generateFilte.Generate();
outStream.Flush(); //Always catches me out
outStream.Position = 0;
return new FileStreamResult(outStream, "application/vnd.ms-excel");

相关内容

  • 没有找到相关文章

最新更新