The EvoPDF HTML to PDF conversion library (http://www.evopdf.com/) claims it supports the Windows Azure Cloud platform, however I can't get it to work. I get the exception:
[Exception: Could not get conversion result header. Data receive error. Could not receive data. Error code: 109]
EvoPdf.HtmlToPdf.ImgConverter.GetLayoutFromUrl(String url, ps& htmlParseInfo) +622
EvoPdf.HtmlToPdf.PdfConverter.ConvertAndGetPdfDocument(String url, String htmlString, String baseUrl, String internalLinksDocUrl, Boolean fromUrl) +9748
EvoPdf.HtmlToPdf.PdfConverter.ConvertAndSaveToStream(Stream outStream, String url, String htmlString, String baseUrl, String internalLinksDocUrl, Boolean fromUrl) +61
EvoPdf.HtmlToPdf.PdfConverter.SavePdfFromUrlToStream(String url, Stream outPdfStream) +20
This looks like its failing at the point where the library fetches the HTML content via a web request. Is there anything in Azure which prevents outgoing web requests?
The library is deployed as two DLLs, a native DLL and a managed assembly - is there any special Azure configuration required to allow native DLLs to be loaded? (The library does support xcopy deployment, I have it working this way in other hosting environments).
From what I can see you need to use and Azure Web Role and not an Azure Web Site. The sites doesn't support running with Full trust.
http://blogs.msdn.com/b/silverlining/archive/2012/06/27/windows-azure-websites-web-roles-and-vms-when-to-use-which.aspx
EvoPdf have an example project for Azure that you can download that shows how to setup up a Web Role with a site that can run the EvoPdf dll.
If the issue is related to your native DLL you might want to try changing the following attributes in the ServiceDefinition.csdef:
- enableNativeCodeExecution: Make sure this is set to true (true is the default)
- executionContext: Try changing this to elevated
And did you deploy the 64-bit version of the DLL?
I also see "Error code: 109" in the error message, can't you contact EvoPDF to ask what this means?
Update: If you're running in ASP.NET, could you try changing the trust level?
<configuration>
<system.web>
<trust level="Full" />
</system.web>
</configuration>
EVO HTML to PDF general library for .NET works directly in Azure Web Roles, Azure Worker Role and Azure Virtual Machines.
For Azure WebSites you can use the EVO HTML to PDF for Azure Websites solution . The code sample copied from there is:
protected void convertToPdfButton_Click(object sender, EventArgs e)
{
// Get the server IP and port
String serverIP = textBoxServerIP.Text;
uint serverPort = uint.Parse(textBoxServerPort.Text);
// Create a HTML to PDF converter object with default settings
HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter(serverIP, serverPort);
// Set optional service password
if (textBoxServicePassword.Text.Length > 0)
htmlToPdfConverter.ServicePassword = textBoxServicePassword.Text;
// Set HTML Viewer width in pixels which is the equivalent in converter of the browser window width
htmlToPdfConverter.HtmlViewerWidth = int.Parse(htmlViewerWidthTextBox.Text);
// Set HTML viewer height in pixels to convert the top part of a HTML page
// Leave it not set to convert the entire HTML
if (htmlViewerHeightTextBox.Text.Length > 0)
htmlToPdfConverter.HtmlViewerHeight = int.Parse(htmlViewerHeightTextBox.Text);
// Set PDF page size which can be a predefined size like A4 or a custom size in points
// Leave it not set to have a default A4 PDF page
htmlToPdfConverter.PdfDocumentOptions.PdfPageSize = SelectedPdfPageSize();
// Set PDF page orientation to Portrait or Landscape
// Leave it not set to have a default Portrait orientation for PDF page
htmlToPdfConverter.PdfDocumentOptions.PdfPageOrientation = SelectedPdfPageOrientation();
// Set the maximum time in seconds to wait for HTML page to be loaded
// Leave it not set for a default 60 seconds maximum wait time
htmlToPdfConverter.NavigationTimeout = int.Parse(navigationTimeoutTextBox.Text);
// Set an adddional delay in seconds to wait for JavaScript or AJAX calls after page load completed
// Set this property to 0 if you don't need to wait for such asynchcronous operations to finish
if (conversionDelayTextBox.Text.Length > 0)
htmlToPdfConverter.ConversionDelay = int.Parse(conversionDelayTextBox.Text);
// The buffer to receive the generated PDF document
byte[] outPdfBuffer = null;
if (convertUrlRadioButton.Checked)
{
string url = urlTextBox.Text;
// Convert the HTML page given by an URL to a PDF document in a memory buffer
outPdfBuffer = htmlToPdfConverter.ConvertUrl(url);
}
else
{
string htmlString = htmlStringTextBox.Text;
string baseUrl = baseUrlTextBox.Text;
// Convert a HTML string with a base URL to a PDF document in a memory buffer
outPdfBuffer = htmlToPdfConverter.ConvertHtml(htmlString, baseUrl);
}
// Send the PDF as response to browser
// Set response content type
Response.AddHeader("Content-Type", "application/pdf");
// Instruct the browser to open the PDF file as an attachment or inline
Response.AddHeader("Content-Disposition", String.Format("{0}; filename=Getting_Started.pdf; size={1}",
openInlineCheckBox.Checked ? "inline" : "attachment", outPdfBuffer.Length.ToString()));
// Write the PDF document buffer to HTTP response
Response.BinaryWrite(outPdfBuffer);
// End the HTTP response and stop the current page processing
Response.End();
}
Include .dat file
Did you copy/include evointernal.dat to the site as well? This solved the error 109 for me. It should reside in the same folder as the *.dll file.
Background: DLL + DAT file
The EVO HTML to PDF library consists of three files:
- evohtmltopdf.dll
- evohtmltopdf.xml
- evointernal.dat
Note that after updating the DLL, do update the evointernal.dat as well. Otherwise the 109 error will reoccur.