发送http标头后,服务器无法附加标头[DotNetZip lib]

时间:2018-01-11 10:01:52

标签: c# asp.net-mvc csv dotnetzip

我有一个名为Logs的表,根据Machine1列存储了不同的记录,

**我正在努力实现**

要导出特定Today's列的Machine1条记录,到目前为止,此代码段只能运行一次,但是对于第二次迭代,会抛出异常“server cannot append header after http headers have been sent”

**我读过很多关于它的信息**

简单来说; "一个请求一个响应"我接下来遇到的是DotNetZip

**我不知道如何将文件添加到zip?**

我原来的功能:

  public void ExportDailyCSV(/*string machine*/)
        {

            var machineList = db.Machines.ToList();
            foreach (var mk in machineList)
            {

                var sb = new StringBuilder();
                var list = (from o in db.Logs
                            where o.Machine == mk.Machine1 && o.sDate == DateTime.Today
                            select o).ToList();
                var fileName = mk.Machine1;
        sb.AppendFormat("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}", "\"Ac-No\"", "\"Name\"", "\"sTime\"", "\"Verify Mode\"", "\"Machine\"", "\"Exception\"", "\"checktype\"", "\"sensorid\"", "\"workcode\"", "\"sDate\"", Environment.NewLine);
                foreach (var item in list)
                {
                    sb.AppendFormat("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}", "\"" + item.Ac_No + "\"", "\"" + item.Name + "\"", "\"" + item.sTime + "\"", "\"" + item.VerifyMode + "\"", "\"" + item.Machine + "\"", "\"" + item.Exception + "\"", "\"" + item.CheckType + "\"", "\"" + item.SensorId + "\"", "\"" + item.WorkCode + "\"", "\"" + item.sDate.Value.ToShortDateString() + "\"", Environment.NewLine);
                }

                try
                {
                    if (System.Web.HttpContext.Current != null)
                    {
                        //Get Current Response  
                        var response = System.Web.HttpContext.Current.Response;
                        response.BufferOutput = true;
                        response.Clear();
                        response.ClearContent();
                        response.ClearHeaders();
                        response.ContentEncoding = Encoding.Unicode;
                        response.ContentEncoding = Encoding.Default;
                        var attachmentValue = string.Format("attachment;filename={0}.csv", fileName);
                        response.AddHeader("content-disposition", attachmentValue);
                        response.ContentType = "text/csv";
                        response.Write(sb.ToString());
                        response.End();
                    }

                }
                catch (ArgumentNullException ex)
                {
                    Response.Write("Property: " + ex.ParamName + " Error: " + ex.Message);
                }
                Task.Delay(300000).ContinueWith(t => ExportDailyCSV());
        }
    }

DotNetZip示例:

uisng (ZipFile zip = new ZipFile())
 {
     // add this map file into the "images" directory in the zip archive
     zip.AddFile("c:\\images\\personal\\7440-N49th.png", "images");
     // add the report into a different directory in the archive
     zip.AddFile("c:\\Reports\\2008-Regional-Sales-Report.pdf", "files");
     zip.AddFile("ReadMe.txt");
     zip.Save("MyZipFile.zip");
 }

如何将它们合并?或者使用DotNetZip进行多次调用,就像我原来的func一样?

1 个答案:

答案 0 :(得分:0)

如果您的目标是只编译CSV并将其作为下载文件返回,您可以先完全读取所有数据,然后构建CSV,然后将其作为一个流响应返回。然后,浏览器和Web服务器将处理其余部分(如实际的流式下载)。

例如:

public class LogsController : ApiController
{
    public HttpResponseMessage Get()
    {
        var machineList = db.Machines.ToList();
        var sb = new StringBuilder();

        foreach (var mk in machineList)
        {

            var list = (from o in db.Logs
                        where o.Machine == mk.Machine1 && o.sDate == DateTime.Today
                        select o).ToList();
            var fileName = mk.Machine1;
    sb.AppendFormat("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}", "\"Ac-No\"", "\"Name\"", "\"sTime\"", "\"Verify Mode\"", "\"Machine\"", "\"Exception\"", "\"checktype\"", "\"sensorid\"", "\"workcode\"", "\"sDate\"", Environment.NewLine);
            foreach (var item in list)
            {
                sb.AppendFormat("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}", "\"" + item.Ac_No + "\"", "\"" + item.Name + "\"", "\"" + item.sTime + "\"", "\"" + item.VerifyMode + "\"", "\"" + item.Machine + "\"", "\"" + item.Exception + "\"", "\"" + item.CheckType + "\"", "\"" + item.SensorId + "\"", "\"" + item.WorkCode + "\"", "\"" + item.sDate.Value.ToShortDateString() + "\"", Environment.NewLine);
            }
        }

        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);

        var stream = new MemoryStream(Encoding.ASCII.GetBytes(sb.ToString()));

        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
        result.Content.Headers.ContentDisposition.FileName = filename;

        return result;
    }

}

这假定文件足够小,可以为每个请求加载到Web服务器的内存中。如果文件非常大,您始终可以将它们写入磁盘,然后返回标准文件流,而不是示例中的内存流。只需记住在完成后清理文件(例如使用finally块)。