HTTP标头问题

时间:2015-09-16 09:23:59

标签: c# .net http model-view-controller

我正在研究.NET 4.5.3上的MVC5项目。我有@Html.BeginForm的视图和 FormMethod.Post 这个视图调用[HttpPost] ActionResult。在Controller中,我从提交的表单中获取必要的ID,然后将其传递给出口。

    [HttpPost]
    public ActionResult PrepareForExport()
    {
        ExportService export = new ExportService();
        if (Request.Form["button"] != null)
        {
            string selected = Request.Form["button"].ToString();
            export.GeneratePdf(ptoRequestsService.GetByID(Convert.ToInt32(selected)));
        }
        else if (Request.Form["toExport"] != null)
        {
            List<PtoRequest> ptoListForExport = new List<PtoRequest>();
            string selectedItems = Request.Form["toExport"].ToString();
            string[] selectedList = selectedItems.Split(',');
            foreach (var pto in selectedList)
            {
                ptoListForExport.Add(ptoRequestsService.GetByID(Convert.ToInt32(pto)));
            }
            export.GenerateZip(ptoListForExport);
        }
        return RedirectToAction("Requests" + LoggedUser.ID);
    }

在ExportService类中,我有这种导出方法。

public void GenerateZip(List<PtoRequest> approvedPtos)
    {
        byte[] pdfContent = null;
        string dateFormat = "yyyy-MM-dd";
        string filePath = null;
        if (!Directory.Exists(HttpContext.Current.Server.MapPath(@"~/Files/PdfFiles/")))
        {
            Directory.CreateDirectory(HttpContext.Current.Server.MapPath("~/Files/PdfFiles/"));
            filePath = HttpContext.Current.Server.MapPath("~/Files/PdfFiles/");
        }
        else
        {
            filePath = HttpContext.Current.Server.MapPath("~/Files/PdfFiles/");
        }
        foreach (var Pto in approvedPtos)
        {
            pdfContent = FillPdfTemplate(Pto);
            string fileName = Pto.User.FirstName + " " + Pto.User.LastName + "_" + Pto.StartDate.ToString(dateFormat) + ".pdf";
            string fileDirectory = filePath + fileName;
            using (FileStream fs = new FileStream(fileDirectory, FileMode.OpenOrCreate))
            {
                fs.Write(pdfContent, 0, pdfContent.Length);
            }
        }
        string zipName = String.Format("Report_{0}.zip", DateTime.Now.ToString("yyyy-mm-dd-HHmmss"));
        string zipFile = filePath + zipName;
        using (ZipFile zip = new ZipFile())
        {
            zip.AddDirectory(filePath);
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.BufferOutput = false;
            HttpContext.Current.Response.ContentType = "application/zip";
            HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + zipName);
            zip.Save(HttpContext.Current.Response.OutputStream);
            HttpContext.Current.Response.Write(zip.ToString());
            HttpContext.Current.Response.End();
            Directory.Delete(filePath, true);
        }
    }

一切正常,但是当我的方法完成工作时,我得到了代码500的异常。我使用谷歌搜索来理解我的问题,它就像这样1。我知道问题出在HttpHeader中,但在我的情况下不明白如何解决它。然后我尝试使用if (!Response.IsRequestBeingRedirected)的解决方案,但我仍然有这个例外。在此之后,我尝试从GenerateZip方法返回ZipFile,而是在ExportService类中调用Response以在Controller调用它,但我仍然遇到此错误。我有一个想法是删除[HttpPost]属性并以其他方式获取我的ID,但我的观点是这样做。任何人都可以指向我解决这个问题吗?什么是正确的决定,在这种情况下我应该在哪里调用Response,是否可以选择编写jQuery脚本以防止在.cshtml中提交表单?

1 个答案:

答案 0 :(得分:3)

您正在调用HttpContext.Current.Response.End();在您的GenerateZip方法中,然后尝试在ControllerAction中重定向用户。这导致您的&#34;在发送响应后无法写入标题#34;错误。而不是那样,从GenerateZip方法返回一个字节数组或Stream对象(FileStream?),并在Action中返回一个FileResult。在文件下载后重定向用户可以(仅?)使用JavaScript实现。这是一个例子。 How to return a FileResult AND RedirectToAction in ASP.NET MVC