2015-03-09 1 views
2

Я использую Rotativa tool для отображения PDF. Он отлично работает на localhost, но не работает на платформе Azure.Я использую инструмент Rotativa для отображения pdf. Он отлично работает на localhost, но не работает на платформе Azure

Ниже мой код ...

public ActionResult GeneratePDF(int id = 0) 
    { 
     ReportTransactionData reporttransactiondata = db.ReportTransactionDatas.Find(id); 
     var viewFileToPrint = @"~/Views/ReportTranData/PDFReport.cshtml"; 
     //var oRotativaPDF = new Rotativa.ViewAsPdf(); 
     var oRotativaPDF = new Rotativa.PartialViewAsPdf(); 
     try 
     { 
      if (reporttransactiondata == null) 
      { 
       return HttpNotFound(); 
      } 
      else 
      { 
       // Populate reporttransactiondata with Verfier Name...TO BE IMPLEMENTED LATER... 
       //reporttransactiondata.VerifierName = GetVerifierNameByID(reporttransactiondata.VerifierID); 
      } 

      // Code to call a function/action... 
      //return new Rotativa.ActionAsPdf("PrintRptInPDF", reporttransactiondata) 

      //oRotativaPDF = new Rotativa.ViewAsPdf(viewFileToPrint, reporttransactiondata) 
      //  { 
      //   FileName = "Technician Job Report.pdf", 
      //   PageSize = Size.A4, 
      //   PageOrientation = Orientation.Portrait, 
      //   PageMargins = new Margins(0, 0, 0, 0), 
      //   PageWidth = 230,  //250  //300 // 350 
      //   PageHeight = 360,  // 380 // 400 //420 // 450 
      //   CustomSwitches = "--disable-smart-shrinking" 
      //  }; 

      oRotativaPDF = new Rotativa.PartialViewAsPdf(viewFileToPrint, reporttransactiondata) 
      { 
       FileName = "Technician Job Report.pdf", 
       PageSize = Size.A4, 
       PageOrientation = Orientation.Portrait, 
       PageMargins = new Margins(0, 0, 0, 0), 
       PageWidth = 230,  //250  //300 // 350 
       PageHeight = 360,  // 380 // 400 //420 // 450 
       CustomSwitches = "--disable-smart-shrinking" 
      }; 
     } 
     catch (Exception ex) 
     { 
      // TODO: Code here... 
     } 

     return oRotativaPDF; 
    } 

Игнорируйте комментируемой код. Это работает отлично, но когда я развертываю свое веб-приложение, файл PDF не загружается с клиентской стороны, и через некоторое время мой браузер IE отображает 500 внутренних ошибок сервера.

Я изучил этот вопрос и узнал, что эта ошибка может быть вызвана тем, что wkhtmltopdf.exe не выполняет самостоятельно на платформе Azure. Так что я пришел со следующим раствором с помощью некоторого поиска в сети о разрешении вопроса ...

общественного ActionResult GeneratePDF (интермедиат ID = 0) { ReportTransactionData reporttransactiondata = db.ReportTransactionDatas.Find (ID) ; string viewName = @ "~/Views/ReportTranData/PDFReport.cshtml"; string wkhtmltopdfPath = Server.MapPath (@ "~/Rotativa /"); Строковые переключатели = string.Empty; try { if (reporttransactiondata == null) { return HttpNotFound(); }

  string fullPath = Server.MapPath(@"~/ApplicationFiles/TechnicianJobReport.pdf"); 
      FileInfo objFileInfo = new System.IO.FileInfo(fullPath); 
      if (objFileInfo.Exists) 
      { 
       objFileInfo.Delete(); 
      } 

      string sViewString = RenderRazorViewToString(viewName, reporttransactiondata); 
      var byteArray = ConvertHTMLtoPDF(wkhtmltopdfPath, switches, sViewString); 
      var fileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write); 
      fileStream.Write(byteArray, 0, byteArray.Length); 
      fileStream.Close(); 

      // Download file at client side... 
      Response.Clear(); 
      Response.ClearContent(); 
      Response.ClearHeaders(); 
      Response.Charset = "UTF-8"; 
      Response.ContentEncoding = Encoding.UTF8; 
      Response.AddHeader("Content-Disposition", "attachment; filename=" + Server.UrlEncode(objFileInfo.Name)); 
      Response.ContentType = "application/pdf"; 
      Response.WriteFile(objFileInfo.FullName); 
      Response.End(); 

     } 
     catch (Exception ex) 
     { 
      // Handle exception here and Log Error to file... 
      Repositories.Repository objRepository = new Repositories.Repository(); 
      string sLogFilePath = Server.MapPath(@"~/ApplicationFiles/ErrorLogFile.txt"); 
      objRepository.LogErrorToFile(ex, sLogFilePath, this.ControllerContext.Controller.ToString()); 
     } 

     return View(reporttransactiondata); 
    } 
    public string RenderRazorViewToString(string viewName, object model) 
    { 
     ViewData.Model = model; 
     using (var sw = new StringWriter()) 
     { 
      var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext,viewName); 
      var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); 
      viewResult.View.Render(viewContext, sw); 
      viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View); 
      return sw.GetStringBuilder().ToString(); 
     } 
    } 

    /// <summary> 
    /// Converts given URL or HTML string to PDF. 
    /// </summary> 
    /// <param name="wkhtmltopdfPath">Path to wkthmltopdf.</param> 
    /// <param name="switches">Switches that will be passed to wkhtmltopdf binary.</param> 
    /// <param name="html">String containing HTML code that should be converted to PDF.</param> 
    /// <returns>PDF as byte array.</returns> 
    private static byte[] ConvertHTMLtoPDF(string wkhtmltopdfPath, string switches, string html) 
    { 
     // switches: 
     //  "-q" - silent output, only errors - no progress messages 
     //  " -" - switch output to stdout 
     //  "- -" - switch input to stdin and output to stdout 
     switches = "-q " + switches + " -"; 

     // generate PDF from given HTML string, not from URL 
     if (!string.IsNullOrEmpty(html)) 
      switches += " -"; 

     var proc = new Process 
     { 
      StartInfo = new ProcessStartInfo 
      { 
       FileName = Path.Combine(wkhtmltopdfPath, "wkhtmltopdf.exe"), 
       Arguments = switches, 
       UseShellExecute = false, 
       RedirectStandardOutput = true, 
       RedirectStandardError = true, 
       RedirectStandardInput = true, 
       WorkingDirectory = wkhtmltopdfPath, 
       CreateNoWindow = true 
      } 
     }; 
     proc.Start(); 

     // generate PDF from given HTML string, not from URL 
     if (!string.IsNullOrEmpty(html)) 
     { 
      using (var sIn = proc.StandardInput) 
      { 
       sIn.WriteLine(html); 
      } 
     } 

     var ms = new MemoryStream(); 
     using (var sOut = proc.StandardOutput.BaseStream) 
     { 
      byte[] buffer = new byte[4096]; 
      int read; 

      while ((read = sOut.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       ms.Write(buffer, 0, read); 
      } 
     } 

     string error = proc.StandardError.ReadToEnd(); 

     if (ms.Length == 0) 
     { 
      throw new Exception(error); 
     } 

     proc.WaitForExit(); 

     return ms.ToArray(); 
    } 

Но это опять-таки отлично работает на локальный, а не на Лазурном сервере и дает тот же 500 внутренняя ошибка сервера без исключения на всех. Посмотрите, может ли здесь кто-нибудь помочь. Я использую этот whtmltopdf exe, потому что я могу указать высоту и ширину pdf в соответствии с моим размером бумаги (размером с размер страницы A4). Если есть какой-либо другой вариант, когда я не могу попасть в вопрос об использовании внешнего exe или dll, предложите этот вариант тоже.

+0

Просьба предоставить трассировку стека, чтобы помочь отлаживать. –

+0

Нет доступных стоп-кадров. Это ошибка сервера IE 500. Приложение работает около 45 секунд, а затем белая страница IE с сообщением о 500 ошибках сервера. Это все, что у меня есть. –

+0

Является ли это развертыванием веб-сайта или веб-сайта? Попробуйте развернуть с помощью web.config, который отключает пользовательские ошибки, чтобы вы могли просматривать стек. –

ответ

7

Нравится (#Fabrizio Accatino) написал (а): Rotativa работает wkhtmltopdf.exe. Он находится в папке «Rotativa» под корнем вашего проекта. Так что этот вопрос может быть:

  1. Во время развертывания - папка Rotativa не создается (убедитесь, что вы добавили папку и EXE-файл в проекте и задать свойство файла, как «копия всегда»).
  2. Есть недостающие библиотеки на сервере (убедитесь, что представлены на сервере - msvcp120.dll и msvcr120.dll/под папкой Syswow64 /)
  3. Убедитесь, что пользователь приложения пула имеет необходимые разрешения для запуска исполняемого файла и сохранить файл temp .pdf.
  4. Убедитесь, что имя пути не превышает максимальную длину (на мой взгляд, 250 цифр).

Я надеюсь, что это поможет вам решить проблему.

+2

Отсутствует dll's может быть установлена ​​с https://www.microsoft. com/en-GB/download/details.aspx? id = 40784 (версия x86) –

+0

@peev Просто чтобы подтвердить, значит ли это, что я должен зафиксировать файл wkhtmltopdf.exe с папкой Rotativa в исходном элементе управления? Если это так, кажется немного странным, делая это, в отличие от пакета nuget, восстанавливающего необходимые бит и куски! –