WkHtmlToPdf в .NET 8 Blazor WebAssembly на стороне сервера завершается сбоем при последующих преобразованияхC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 WkHtmlToPdf в .NET 8 Blazor WebAssembly на стороне сервера завершается сбоем при последующих преобразованиях

Сообщение Anonymous »

Я работаю над приложением .NET 8 Blazor WebAssembly (на стороне сервера), где я конвертирую HTML в PDF с помощью WkHtmlToPdf. Я использую wkhtmltox.dll непосредственно из папки сервера проекта.
Преобразование работает нормально в первый раз, но при последующих попытках оно либо:
  • Зависает на строке преобразования или
  • Создает PDF-файл, содержащий только простой текст, без каких-либо HTML-тегов, CSS или изображений. .
Я пробовал разные подходы, включая вызов wkhtmltopdf_deinit() в деструкторе и даже в блоке Final, но проблема сохраняется. Похоже, что-то идет не так после первого успешного преобразования.
Вот соответствующий код:
Класс обслуживания:

Код: Выделить всё

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:
(Необходимые методы взаимодействия реализованы правильно.)

Код: Выделить всё

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);
}
Регистрация услуги:

Код: Выделить всё

builder.Services.AddSingleton();
Что я пробовал:
  • Переместил wkhtmltopdf_deinit() вызов блокаfinally. Это устраняет проблему зависания приложения, но при последующих преобразованиях сгенерированный PDF-файл содержит только простой текст и игнорирует все форматирование (без заголовков, изображений или CSS).
  • Проверено без создания службу и напрямую вызвал методы DLL, но проблема остается.
  • Пересоздание проекта временно устраняет проблему, но та же проблема возникает снова после первого преобразования.
  • Я также пытался сменить службу с Singleton на AddScoped или AddTransient.
Я застрял на этом последние несколько дней и Кажется, не могу понять, почему преобразование ведет себя таким образом после первой попытки. Есть ли у кого-нибудь идеи, что может быть причиной этой проблемы и как ее решить?
Будем очень признательны за любые рекомендации или предложения.

Подробнее здесь: https://stackoverflow.com/questions/790 ... nt-convers
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»