2012-02-16 1 views
3

Я получаю ошибку «Документ не открыт» в iTextSharp, но только в производстве. Код работает отлично на моей машине dev и в стадии. У меня одинаковые разрешения, установленные в папке Temp на сервере сцены.Ошибка «Документ не открыт» только в производстве с iTextSharp

public static byte[] ConvertHtmlToPdf(string html) 
    { 
     html = HtmlPostProcessor.Process(html); 
     byte[] fileData = null; 
     string tempPath = ConfigurationManager.AppSettings["TempDirectory"]; 
     string tempPDFFile = Path.Combine(tempPath, Guid.NewGuid() + ".pdf"); 
     int num = FontFactory.RegisterDirectory(@"C:\Windows\Fonts"); 

     using (FileStream fs = new FileStream(tempPDFFile, FileMode.Create)) 
     { 
      using (Document document = new Document(PageSize.LETTER, 50, 50, 50, 50)) 
      { 
       document.Open(); 
       PdfWriter.GetInstance(document, fs); 
       using (StringReader stringReader = new StringReader(html)) 
       { 

        List<IElement> parsedList = HTMLWorker.ParseToList(stringReader, null); 
        foreach (IElement item in parsedList) 
        { 
         document.Add(item); 
        } 
       } 
      } 
     } 

     FileStream generatedPDF = File.Open(tempPDFFile, FileMode.Open); 
     fileData = new byte[(int)generatedPDF.Length]; 
     int result = generatedPDF.Read(fileData, 0, (int)generatedPDF.Length); 

     generatedPDF.Close(); 

     File.Delete(tempPDFFile); 

     return fileData; 
    } 

Файл PDF действительно становится создан, так что я знаю, что проходит мимо

using (FileStream fs = new FileStream(tempPDFFile, FileMode.Create)) 

по крайней мере.

Этот код работает очень хорошо в dev и организует, но это порождает ошибку в производстве. Любые мысли о том, почему это может быть?

+1

Существует ли конкретная причина создания временного файла на сервере? В противном случае просто замените «FileStream» в вашем коде «MemoryStream», а затем вызовите 'ms.ToArray()', чтобы вернуть 'byte []'. Затем вы также устраняете дополнительные шаги, связанные с чтением временного файла, а затем удаляете его ... – kuujinbo

+0

Его хорошее предложение и предположение, которое я видел раньше, однако это не то, что вызывает проблему. Спасибо хоть. – capn

ответ

3

Использование предложения kuujinbo в об улучшении кода, теперь он выглядит следующим образом:

public static byte[] ConvertHtmlToPdf(string html) 
    { 
     html = HtmlPostProcessor.Process(html); 
     byte[] fileData = null; 
     int num = FontFactory.RegisterDirectory(@"C:\Windows\Fonts"); 

     using (MemoryStream ms = new MemoryStream(html.Length)) 
     { 
      using (Document document = new Document(PageSize.LETTER, 50, 50, 50, 50)) 
      { 
       PdfWriter.GetInstance(document, ms); 
       using (StringReader stringReader = new StringReader(html)) 
       { 

        List<IElement> parsedList = HTMLWorker.ParseToList(stringReader, null); 
        document.Open(); 
        foreach (IElement item in parsedList) 
        { 
         document.Add(item); 
        } 
       } 
      } 

      fileData = ms.ToArray(); 
     } 
     return fileData; 
    } 

Проблема заключалась в том, что внутри:

using (Document document = new Document(PageSize.LETTER, 50, 50, 50, 50)) 

заявление, другое исключение броска, в моем случае это был:

WebException: Unable to connect to the remote server 

, который произошел из-за того, что изображение, которое я использовал, было связано внутри документа HTML, который преобразовывался в P DF, указывал на другой веб-сайт, размещенный на том же сервере. У сервера были внутренние и внешние IP-адреса, но я забыл отредактировать файл hosts на сервере, так что перенаправление к себе с использованием этих имен DNS будет использовать внутренние адреса вместо внешних.

Причина, по которой сообщение «Исключение» было «Документ не открыт», потому что (FYI: Я принимаю здесь), поскольку я был в блоке, который в основном действует как «окончательный» оператор, в любое время исключение в библиотеке iText, Документ закрывается, а при попытке использования Dispose (что было обнаружено в трассировке стека) iText ошибочно, поскольку объект Document уже должен быть закрыт.

13

не заметил его на первый взгляд, но из кода выше:

document.Open(); 
PdfWriter.GetInstance(document, fs); 

Порядок должен быть обратным:

PdfWriter.GetInstance(document, fs); 
document.Open(); 

Другими словами, вам нужно PdfWriterдо вы пытаетесь открыть Document

+0

Да, это было после того, как я пробовал пару разных вещей, чтобы заставить его сломаться по-другому, чтобы получить еще одно сообщение об ошибке или что-то в этом роде, я получил его, я опубликую ответ в нескольких, но это было что-то не так что я должен был отменить. – capn

Смежные вопросы