Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

WkHtmlToPdf in .NET 8 Blazor WebAssembly Server Side Fails on Subsequent Conversions

$
0
0

I am working on a .NET 8 Blazor WebAssembly application (server-side) where I am converting HTML to PDF using WkHtmlToPdf. I'm using the wkhtmltox.dll directly from the project’s server folder.

The conversion works fine the first time, but on subsequent attempts, it either:

  1. Hangs on the conversion line, or
  2. Generates a PDF that contains only plain text without following any HTML tags, CSS, or images.

I tried different approaches, including calling wkhtmltopdf_deinit() in the destructor and even in the finally block, but the issue persists. It seems like something is going wrong after the first successful conversion.

Here is the relevant code:

Service Class:

public class TestService{    public TestService()    {        WkHtmlToPdfInterop.wkhtmltopdf_init(0);    }    ~TestService()    {        WkHtmlToPdfInterop.wkhtmltopdf_deinit();    }    public byte[] ConvertHtmlToPdf(string html)    {        IntPtr globalSettings = WkHtmlToPdfInterop.wkhtmltopdf_create_global_settings();        string tempFilePath = Path.GetTempFileName() +".pdf"; // Create a temp file with .pdf extension        WkHtmlToPdfInterop.wkhtmltopdf_set_global_setting(globalSettings, "out", tempFilePath);        IntPtr converter = WkHtmlToPdfInterop.wkhtmltopdf_create_converter(globalSettings);        IntPtr htmlPtr = Marshal.StringToHGlobalAnsi(html);        IntPtr objectSettings = WkHtmlToPdfInterop.wkhtmltopdf_create_object_settings();        try        {            WkHtmlToPdfInterop.wkhtmltopdf_add_object(converter, objectSettings, htmlPtr);            int result = WkHtmlToPdfInterop.wkhtmltopdf_convert(converter);            if (result == 0)            {                throw new Exception("PDF conversion failed.");            }            byte[] pdfBytes = System.IO.File.ReadAllBytes(tempFilePath);            Marshal.FreeHGlobal(htmlPtr);            WkHtmlToPdfInterop.wkhtmltopdf_destroy_converter(converter);            WkHtmlToPdfInterop.wkhtmltopdf_destroy_object_settings(objectSettings);            WkHtmlToPdfInterop.wkhtmltopdf_destroy_global_settings(globalSettings);            if (System.IO.File.Exists(tempFilePath)) System.IO.File.Delete(tempFilePath);            return pdfBytes;        }        finally        {        }    }

WkHtmlToPdfInterop Class:(The necessary interop methods are properly implemented.)

public static class WkHtmlToPdfInterop{    private const string DllName = "wkhtmltox"; // Change based on platform    // Initialize the library    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern int wkhtmltopdf_init(int use_graphics);    // Deinitialize the library    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern int wkhtmltopdf_deinit();    // Create global settings    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern IntPtr wkhtmltopdf_create_global_settings();    // Create converter with global settings    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern IntPtr wkhtmltopdf_create_converter(IntPtr globalSettings);    // Add an object (HTML content)    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern void wkhtmltopdf_add_object(IntPtr converter, IntPtr objectSettings, IntPtr data);    // Convert HTML to PDF    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern int wkhtmltopdf_convert(IntPtr converter);    // Destroy the converter    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern void wkhtmltopdf_destroy_converter(IntPtr converter);    // Set a global setting    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern int wkhtmltopdf_set_global_setting(IntPtr settings, string name, string value);    // Create object settings    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern IntPtr wkhtmltopdf_create_object_settings();    // Set an object setting    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern int wkhtmltopdf_set_object_setting(IntPtr objectSettings, string name, string value);    // Destroy object settings    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern void wkhtmltopdf_destroy_object_settings(IntPtr objectSettings);    [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]    public static extern void wkhtmltopdf_destroy_global_settings(IntPtr objectSettings);}

Service Registration:

builder.Services.AddSingleton<TestService>();

What I've Tried:

  1. Moved the wkhtmltopdf_deinit() call to the finally block. This fixes the issue of the application getting stuck, but on subsequent conversions, the generated PDF only contains plain text and ignores all formatting (no headings, images, or CSS).
  2. Tried without creating a service and called the DLL methods directly, but the issue persists.
  3. Rebuilding the project temporarily fixes the issue, but the same problem happens again after the first conversion.
  4. I also Tried to change service from Singleton to AddScoped or AddTransient.

I’ve been stuck on this for the last few days and can’t seem to figure out why the conversion behaves this way after the first attempt. Does anyone have any idea what could be causing this issue and how to resolve it?

Any guidance or suggestions would be greatly appreciated.


Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>