2015-09-16 2 views
0

Я работаю над проектом MVC5 на .NET 4.5.3. У меня есть View with @ Html.BeginForm и FormMethod.Post этот вид вызывает [HttpPost] ActionResult. В контроллере я получаю необходимые идентификаторы из представленной формы, а затем передаю их для экспорта.HTTP Header Issue

[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), но у меня все еще есть это исключение. После этого я попытался вернуть ZipFile из метода GenerateZip и вместо этого вызвать Response в классе ExportService, чтобы вызвать его на контроллере, но у меня все еще есть эта ошибка. У меня есть идея удалить атрибут [HttpPost] и взять мой идентификатор другим способом, но я должен сделать так. Может ли кто-нибудь указать мне в любом направлении на решение этого? Какое правильное решение, где я должен назвать Response для этого случая, есть ли возможность написать сценарий jQuery, чтобы предотвратить отправку формы в .cshtml?

ответ

3

Вы вызываете HttpContext.Current.Response.End(); в вашем методе GenerateZip, а затем попытаться перенаправить пользователя в ControllerAction. Это приводит к тому, что ошибка «Заголовки не могут быть записаны после отправки ответа». Вместо этого верните массив байтов или объект Stream (FileStream?) Из метода GenerateZip и верните FileResult в Action. Перенаправить пользователя после загрузки файла можно (только?), Используя JavaScript. Вот пример. How to return a FileResult AND RedirectToAction in ASP.NET MVC

+0

Извините, что прокомментировал мой последний комментарий. Я попробую это, и если вы хотите, я дам вам знать о результате. Спасибо за ваше время. –