How to Generate PDFs in ASP.NET Core on Azure Using wkhtmltopdf and DinkToPDF

Generating a PDF from HTML in ASP.NET Core can work perfectly during local development and still fail after the same application is deployed to Azure App Service.

The problem is often not the C# code itself.

PDF libraries such as wkhtmltopdf and DinkToPDF depend on native components, system resources, fonts and operating-system-level behavior. Azure App Service introduces a different execution environment, which can expose dependency or resource issues that were not visible locally.

In this guide, we will cover:

  • How to generate PDFs in ASP.NET Core using wkhtmltopdf
  • How to use DinkToPDF with .NET Core
  • How [page] and [toPage] work in DinkToPDF
  • Why PagesCount = true matters
  • How to configure DinkToPDF headers and footers
  • Why PDF generation may fail after Azure deployment
  • Azure Windows vs Linux considerations
  • Common timeout, font and dependency issues
  • What our testing showed on different Azure App Service configurations

Quick Answer: How Do You Generate a PDF in ASP.NET Core on Azure?

ASP.NET Core applications can generate PDFs using tools such as wkhtmltopdf, wrappers such as DinkToPDF, or MVC-oriented libraries such as Rotativa.

The implementation itself is only part of the decision. For Azure-hosted applications, also evaluate:

FactorWhy It Matters
Azure operating systemNative binaries can behave differently on Linux and Windows
App Service tierResource and sandbox restrictions vary
Native dependencieswkhtmltopdf-based libraries require supporting binaries
CPU architecturex86/x64 must match the deployed native library
FontsFonts available locally may not exist in Azure
PDF requirementsHeaders, footers and page numbers may require additional configuration

For basic HTML-to-PDF generation, wkhtmltopdf can be used directly through a .NET wrapper.

For greater configuration control, DinkToPDF provides a .NET API around wkhtmltopdf, including support for paper size, orientation, margins, headers, footers and page counters.

2026 Technical Note: Is wkhtmltopdf Still Maintained?

The official wkhtmltopdf repository was archived on January 2, 2023 and is now read-only. Its latest listed release is version 0.12.6.

This does not mean every existing wkhtmltopdf implementation needs to be replaced immediately.

Existing applications may continue using it when:

  • The implementation is already stable
  • PDF templates are thoroughly tested
  • The runtime environment is controlled
  • Replacing the rendering engine would require substantial redevelopment

However, teams starting a new long-term application should also evaluate actively maintained PDF-generation approaches before making wkhtmltopdf a new architectural dependency.

Key takeaway: This guide is especially useful for teams maintaining, troubleshooting or improving existing ASP.NET Core applications that already use wkhtmltopdf or DinkToPDF.

What We Tested for ASP.NET Core PDF Generation on Azure

The recommendations in this guide are based partly on practical testing carried out while deploying ASP.NET Core PDF-generation examples to Azure.

AreaTest Context
ApplicationASP.NET Core
Cloud platformAzure App Service
Operating systemsWindows and Linux
PDF toolswkhtmltopdf, DinkToPDF and Rotativa
HostingFree and paid App Service configurations
Output scenariosPDF generation and Azure Blob Storage
Issues observedTimeout, fonts, native dependencies and deployment behavior

The results described in this article should be treated as tested implementation experience rather than universal behavior for every Azure configuration.

Different .NET versions, package versions, App Service tiers and native dependencies can change the result.

DinkToPDF vs wkhtmltopdf vs Rotativa for ASP.NET Core PDF Generation

Choosing between wkhtmltopdf, DinkToPDF and Rotativa depends primarily on how the PDF is created and how much configuration the application requires.

LibraryBest FitImportant Consideration
wkhtmltopdfDirect HTML-to-PDF conversionUses a native rendering engine and requires deployment planning
DinkToPDF.NET applications needing headers, footers, margins and page numberingWraps wkhtmltopdf, so native dependency considerations remain
RotativaASP.NET MVC applications generating PDFs from viewsAlso relies on wkhtmltopdf
Alternative maintained enginesNew systems requiring longer-term maintenanceCompare rendering, licensing, Azure compatibility and support

DinkToPDF is a C# wrapper around wkhtmltopdf, rather than an independent PDF-rendering engine.

Therefore, when wkhtmltopdf cannot load correctly in a hosting environment, a DinkToPDF implementation can also be affected.

For an existing application, choose based on the implementation already in place and the PDF features you require.

For a new application, also consider the maintenance status of the underlying rendering technology.

How to Generate a PDF with wkhtmltopdf in ASP.NET Core

wkhtmltopdf converts HTML content into PDF documents.

ASP.NET Core applications can access it through .NET wrapper packages such as Wkhtmltopdf.NetCore.

A basic implementation involves:

Step 1: Install the .NET Package

Using Package Manager Console:


PM > Install-Package Wkhtmltopdf.NetCore

The current article explicitly hard-codes:

Version 3.0.2

I recommend removing the fixed version unless your development team confirms that this exact version remains the supported version in Satva’s repository.

Package versions should match the application’s .NET/runtime requirements.

A screenshot of a Visual Studio project named "PDFLibraryWebApp" built with Asp.Net Core, displaying the project structure including folders like Dependencies, Properties, PDFs, and files such as appsettings.json, HomeController.cs, Program.cs, and Startup.cs. The project is ready for deployment to Azure.

Step 2: Generate the PDF from HTML

Use a controller or service to pass HTML into the PDF generator.


public class HomeController : Controller
{
    private readonly IGeneratePdf _generatePdf;
    private readonly ILogger<HomeController> _logger;

    public HomeController(
        IGeneratePdf generatePdf,
        ILogger<HomeController> logger)
    {
        _generatePdf = generatePdf;
        _logger = logger;
    }

    public IActionResult Index()
    {
        try
        {
            var html = "<h1 style='color:red'>Hello World</h1>";

            var bytes = _generatePdf.GetPDF(html);

            return File(
                bytes,
                "application/pdf",
                "wkhtmltopdf-example.pdf");
        }
        catch (Exception ex)
        {
            _logger.LogError(
                ex,
                "PDF generation failed.");

            return StatusCode(
                500,
                "PDF generation failed.");
        }
    }
}

This example is useful for confirming whether basic PDF generation works in the local environment.


public class HomeController : Controller
{
    private readonly IGeneratePdf _generatePdf;
    private readonly ILogger<HomeController> _logger;

    public HomeController(
        IGeneratePdf generatePdf,
        ILogger<HomeController> logger)
    {
        _generatePdf = generatePdf;
        _logger = logger;
    }

    [Obsolete]
    public IActionResult Index()
    {
        try
        {
            var htmlContent = "<h1 style='color:red'>Hello World</h1>";

            var bytes = _generatePdf.GetPDF(htmlContent);

            var pdfPath = Path.Combine(
                Environment.ContentRootPath,
                "PDfswkhtmltopdf.pdf"
            );

            System.IO.File.WriteAllBytes(pdfPath, bytes);

            return PhysicalFile(
                pdfPath,
                "application/pdf"
            );
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error generating PDF");

            var errorMessage = ex.InnerException?.Message ?? ex.Message;

            var errorPath = Path.Combine(
                Environment.ContentRootPath,
                "PDfswkhtmltopdfError.txt"
            );

            System.IO.File.WriteAllText(
                errorPath,
                errorMessage
            );

            return PhysicalFile(
                errorPath,
                "text/plain"
            );
        }
    }
}
Here the Library is providing the Interface Service IGeneratePdf. This service has many methods.
Use above code, save and run the application it will open the pdf file in the browser.

Once the implementation works locally, the next step is testing the same code after deployment to Azure App Service.

That is where native dependency, font and hosting-environment differences become important.

How to Run wkhtmltopdf on Azure App Service

A wkhtmltopdf implementation that works locally may fail after Azure deployment because Azure App Service is a different execution environment from a developer workstation.

Before changing the PDF code, validate the following.

Native wkhtmltopdf dependencies

Make sure the required executable or native library is included in the deployed application.

Runtime architecture

The application’s architecture must be compatible with the wkhtmltopdf native dependency.

For example, a 64-bit application should not attempt to load an incompatible 32-bit native library.

Fonts

A font installed locally might not exist in the Azure environment.

This can result in:

  • Different typography
  • Changed line breaks
  • Misaligned content
  • Incorrect PDF layouts

Hosting restrictions

Azure App Service environments may restrict access to operating-system functionality compared with a traditional server or VM.

This is particularly relevant for applications that execute native PDF-rendering components.

wkhtmltopdf Issue on Azure App Service Free Plan

In our original Windows Azure App Service test, wkhtmltopdf did not behave the same way as it did locally.

After adding the required wkhtmltopdf files and running the application, we encountered PDF rendering issues, including incorrect fonts.

Once you run the application and it runs successfully then you will find the pdf with the incorrect fonts.

The behavior depends on factors including:

  • Windows vs Linux hosting
  • Native dependencies
  • App Service restrictions
  • Application architecture
  • wkhtmltopdf build
  • Runtime resources
Screenshot of an Asp.Net Core web app management interface on Azure, featuring essential options for restarting, setting actions, and deployment. Highlights include the restart button and sections like Diagnose and solve problems for optimal performance management.
Screenshot of a PDF document open in an Asp.Net Core browser, showcasing the text "Hello World" in vibrant red.

This result shows what worked in our test environment. It should not be interpreted as evidence that every wkhtmltopdf deployment requires the same Azure tier.

Later in our testing, we were also able to run a wkhtmltopdf-based implementation using an Azure Linux App Service configuration.

2. DinkToPDF .NET Core Complete Example

DinkToPDF provides a .NET interface around wkhtmltopdf and is useful when an application requires additional PDF configuration.

Common settings include:

  • Paper size
  • Orientation
  • Margins
  • HTML content
  • Character encoding
  • Headers
  • Footers
  • Page numbers

A basic global configuration can look like this:


var globalSettings = new GlobalSettings
{
    ColorMode = ColorMode.Color,
    Orientation = Orientation.Portrait,
    PaperSize = PaperKind.A4,
    Margins = new MarginSettings
    {
        Top = 18,
        Bottom = 18
    }
};

Configure the HTML document:

    
var objectSettings = new ObjectSettings
{
    PagesCount = true,

    HtmlContent = htmlContent,

    WebSettings =
    {
        DefaultEncoding = "utf-8"
    },

    HeaderSettings =
    {
        FontSize = 10,
        Right = "Page [page] of [toPage]",
        Line = true
    },

    FooterSettings =
    {
        FontSize = 8,
        Center = "PDF demo",
        Line = true
    }
};

Then create and convert the PDF:

    

var htmlToPdfDocument = new HtmlToPdfDocument
{
    GlobalSettings = globalSettings,
    Objects =
    {
        objectSettings
    }
};

return _converter.Convert(htmlToPdfDocument);

A complete implementation can look like this:


  private byte[] GeneratePdf(string htmlContent)
{
    try
    {
        var globalSettings = new GlobalSettings
        {
            ColorMode = ColorMode.Color,
            Orientation = Orientation.Portrait,
            PaperSize = PaperKind.A4,
            Margins = new MarginSettings
            {
                Top = 18,
                Bottom = 18
            }
        };

        var objectSettings = new ObjectSettings
        {
            PagesCount = true,
            HtmlContent = htmlContent,

            WebSettings =
            {
                DefaultEncoding = "utf-8"
            },

            HeaderSettings =
            {
                FontSize = 10,
                Right = "Page [page] of [toPage]",
                Line = true
            },

            FooterSettings =
            {
                FontSize = 8,
                Center = "PDF demo",
                Line = true
            }
        };

        var document = new HtmlToPdfDocument
        {
            GlobalSettings = globalSettings,
            Objects =
            {
                objectSettings
            }
        };

        return _converter.Convert(document);
    }
    catch (Exception ex)
    {
        _logger.LogError(
            ex,
            "Error generating PDF."
        );

        throw;
    }
}

Because DinkToPDF uses wkhtmltopdf underneath, the appropriate native wkhtmltopdf dependency must also be available in the deployed environment.

  • It will give you options and methods to set the PDF size, margins, etc…
  • I have created one example and here is the main code to use.

private byte[] GeneratePdf(string htmlContent)
{
    try
    {
        _logger.LogInformation("GeneratePdf started.");

        // Configure global settings for the PDF document
        var globalSettings = new GlobalSettings
        {
            ColorMode = ColorMode.Color,
            Orientation = Orientation.Portrait,
            PaperSize = PaperKind.A4,
            Margins = new MarginSettings { Top = 18, Bottom = 18 },
        };

        // Configure object settings for the HTML content
        var objectSettings = new ObjectSettings
        {
            PagesCount = true,
            HtmlContent = htmlContent,
            WebSettings = { DefaultEncoding = "utf-8" },
            HeaderSettings = 
            {
                FontSize = 10,
                Right = "Page [page] of [toPage]",
                Line = true
            },
            FooterSettings = 
            {
                FontSize = 8,
                Center = "PDF demo",
                Line = true
            }
        };

        // Create the PDF document
        var htmlToPdfDocument = new HtmlToPdfDocument
        {
            GlobalSettings = globalSettings,
            Objects = { objectSettings },
        };

        // Convert HTML to PDF
        return _converter.Convert(htmlToPdfDocument);
    }
    catch (Exception ex)
    {
        _logger.LogError("Error in GeneratePdf: {Message}", ex.Message);
        return null;
    }
}
  • So once you download the code and run it it will work locally. Basically, the key thing which is required is DinkToPdf NugetPackage and the folder of v12.0.4. It is the wkhtmltopdf Wrapper.
Screenshot of DinkToPdf package directory with 32 bit and 64 bit subfolders
  • I have used the Invoice template for a demo. And you can find it in the Views folder.
  • Here I used to save the pdf file to Azure Blob Storage after pdf generation. For that please provide your storage key and the pdf file name in the appsettings.json.
  • Once all set the code Host the code into Azure app service. And run.
  • And run this url to get your output : https://{AppServiceName}.azurewebsites.net/documentgenerator

DinkToPDF Timeout Error on Azure App Service

After publishing our DinkToPDF example to Azure App Service, the PDF-generation endpoint returned a timeout in the configuration we were testing.

500 The Request Timed Out

  • Fix for DinkToPDF Timeout Error: In our test, the issue was fixed by moving the application to a paid Azure App Service Production plan, restarting the app, and running the PDF generation process again.
  • Here, I am using the minimum plan for this.
Screenshot of an Asp.Net Core web interface on Azure showing pricing tiers for production-level workloads. The highlighted segment displays the S1 tier with 100 ACU, 1.75 GB memory, and $73.26/month estimated cost.
  • Apply the plan, Restart the app and run, you will get the desired output.
Screenshot from an Asp.Net Core application on Azure displaying a successful PDF upload status message

Text screenshot from an Asp.Net Core application on Azure displaying: “{‘statusCode’: 200, ‘message’: ‘pdf file has been successfully uploaded’}.

  • And when i see in the blob storage.
Screenshot displaying PDF files in Azure Blob Storage

Screenshot displaying a file directory with two PDF files: “GeneratedPdf.pdf” and “RazorTemplatePdf.pdf,” both labeled under the “Hot (inferred)” access tier. These files were efficiently managed using Asp.Net Core within the Azure ecosystem.

  • So it’s all about choosing the right hosting plan and your code works well.

DinkToPDF Page Numbers: How [page] and [toPage] Work

DinkToPDF can display the current PDF page and the document’s total page count through wkhtmltopdf page-number placeholders.

For example, a five-page document can display:


Page 1 of 5
Page 2 of 5
Page 3 of 5
Page 4 of 5
Page 5 of 5

The two important placeholders are:

PlaceholderPurpose
[page]Current PDF page
[toPage]Last page or total page count

DinkToPDF FooterSettings Example for Page [page] of [toPage]

If you want page numbering in the footer, configure it through FooterSettings.


FooterSettings =
{
    FontSize = 8,
    Right = "Page [page] of [toPage]",
    Line = true,
    Spacing = 3
}

For example, the generated footer can display:


Page 3 of 12

A more complete configuration is:


var objectSettings = new ObjectSettings
{
    PagesCount = true,

    HtmlContent = htmlContent,

    WebSettings =
    {
        DefaultEncoding = "utf-8"
    },

    FooterSettings =
    {
        FontSize = 8,
        Right = "Page [page] of [toPage]",
        Line = true,
        Spacing = 3
    }
};

Is PagesCount = true Required in DinkToPDF?

When you need document page counters for headers and footers, configure:


PagesCount = true

inside the relevant ObjectSettings.

A basic example is:


var objectSettings = new ObjectSettings
{
    PagesCount = true,

    HtmlContent = htmlContent,

    FooterSettings =
    {
        Right = "Page [page] of [toPage]"
    }
};

PagesCount tells DinkToPDF to count the pages of the document for page-counter functionality.

This setting is especially relevant when using:


[page]

or:


[toPage]

Why Is [toPage] Not Working in DinkToPDF?

If [toPage] is missing, incorrect or appears as plain text in the PDF, work through these checks.

1. Confirm PagesCount

Make sure:


PagesCount = true

is enabled on the appropriate ObjectSettings.

2. Check the Placeholder

Use:


[toPage]

For example:


Right = "Page [page] of [toPage]"

3. Place It in the Header or Footer Configuration


FooterSettings =
{
    Right = "Page [page] of [toPage]"
}

4. Test a Multi-Page Document

Use enough HTML content to create multiple PDF pages so that the page counter can be tested properly.

5. Verify wkhtmltopdf Dependencies

Because DinkToPDF relies on wkhtmltopdf, a native-library or deployment problem can affect features even if the C# configuration appears correct.

6. Compare Local and Azure Results

If [toPage] works locally but fails after Azure deployment, investigate:

  • Operating system
  • wkhtmltopdf binary
  • Architecture
  • Deployment folders
  • Native-library loading
  • Fonts
  • App Service configuration

DinkToPDF Page Number Troubleshooting Checklist

CheckRecommended Configuration
Enable page countingPagesCount = true
Current page[page]
Total pages[toPage]
Combined formatPage [page] of [toPage]
Header placementHeaderSettings
Footer placementFooterSettings
EncodingUTF-8
Native dependencyCorrect wkhtmltopdf library
Runtime architectureMatch x86/x64
Azure testCompare local and deployed output

DinkToPDF HeaderSettings Example

Page numbers can also be displayed in the document header.


HeaderSettings =
{
    FontSize = 9,
    Right = "Page [page] of [toPage]",
    Line = true,
    Spacing = 3
}

Whether you use the header or footer depends on the document design.

For invoices, reports and statements, footer page numbering is often a natural choice. Technical documents may use either location.

Rotativa PDF Generation in ASP.NET Core

Rotativa is commonly used when an ASP.NET MVC application needs to generate PDFs directly from Razor/MVC views.

It can be convenient because it fits naturally into MVC applications.

However, Rotativa also relies on wkhtmltopdf, so Azure deployment still requires attention to:

  • wkhtmltopdf executable availability
  • Hosting environment
  • Native dependencies
  • Fonts
  • Resource limitations

In our tested Azure configuration, the Free-tier deployment returned a timeout.

Screenshot of a C# class code in an ASP.NET Core namespace, integrating Azure functionalities. The code defines a class for rendering PDF views, with several methods and properties for handling different view formats.
500 The Request Timed Out

Common Azure App Service Issues with PDF Generation

When PDF generation works locally but fails after Azure deployment, use the symptoms to narrow down the likely cause.

ProblemPossible CauseWhat to Check
PDF works locally but not AzureMissing native dependencyVerify wkhtmltopdf binary/library deployment
500 or timeoutResources, dependency loading or slow renderingCheck logs, CPU, memory and document complexity
Incorrect fontsRequired font unavailableTest supported fonts and embedded/web resources
[toPage] incorrectPage counting/configurationVerify PagesCount = true
Page number missingHeader/footer settingsVerify [page] and [toPage] placement
Library fails to loadArchitecture mismatchCheck x86 vs x64
Different PDF layoutRendering/environment differenceCompare fonts, CSS and external resources
Images are missingResource inaccessible from serverTest URL accessibility and authentication
Azure-only failureHosting restrictionCompare local environment with App Service

Should You Use a Custom Container for wkhtmltopdf on Azure?

A custom container is worth considering when the application requires tighter control over native PDF-generation dependencies.

A container can package the application together with:

  • wkhtmltopdf
  • Linux or Windows dependencies
  • Fonts
  • .NET runtime
  • Other required system libraries

Azure App Service supports custom container deployments, including custom Linux images.

This can make the runtime environment more predictable than depending on packages or system components already installed by the host.

A container may be particularly useful when:

  • Multiple native packages are required
  • wkhtmltopdf dependencies differ between environments
  • Custom fonts are required
  • The team wants repeatable development, staging and production environments

Containers add deployment and maintenance responsibilities, so they should be chosen because the architecture benefits from them, not simply as a workaround for every PDF issue.

Generate PDF on Azure App Service Free Plan using Linux

In Satva’s tested configuration, we were able to run a wkhtmltopdf ASP.NET Core implementation using Azure App Service on Linux with the Free tier.

This was different from the earlier Windows App Service configuration we tested.

The important point is that this was the result of a specific test configuration, not a guarantee that every wkhtmltopdf/.NET/Azure Linux combination will behave identically.

The same areas still need verification:

  • wkhtmltopdf binary compatibility
  • Linux dependencies
  • Application runtime
  • Fonts
  • Deployment configuration

 


public class HomeController : Controller
{
    private readonly IGeneratePdf _generatePdf;
    private readonly ILogger<HomeController> _logger;
    private readonly IFileProvider _fileProvider;
    private readonly IConfiguration _config; // Ensure you have a configuration instance injected

    public HomeController(IGeneratePdf generatePdf, ILogger<HomeController> logger, IFileProvider fileProvider, IConfiguration config)
    {
        _generatePdf = generatePdf;
        _logger = logger;
        _fileProvider = fileProvider;
        _config = config; // Initialize the configuration instance
    }

    [Obsolete]
    public async Task<IActionResult> Index()
    {
        try
        {
            // Generate PDF
            var bytes = _generatePdf.GetPDF("<h1 style='color:red'>Hello World</h1>");
            
            // Retrieve storage configuration values
            var connString = _config.GetValue<string>("StorageKey") ?? string.Empty;
            var blobContainer = _config.GetValue<string>("blobContainer") ?? string.Empty;
            var blobName = _config.GetValue<string>("blobName") ?? string.Empty;

            // Create the blob client
            var storageAccount = CloudStorageAccount.Parse(connString);
            var blobClient = storageAccount.CreateCloudBlobClient();

            // Retrieve reference to the container and blob
            var container = blobClient.GetContainerReference(blobContainer);
            var blockBlob = container.GetBlockBlobReference(blobName);

            // Upload the byte array to the blob asynchronously
            await blockBlob.UploadFromByteArrayAsync(bytes, 0, bytes.Length);

            return Ok(new { Message = "File has been uploaded successfully." });
        }
        catch (Exception ex)
        {
            // Log the error
            _logger.LogError("Error: {Message}", ex);

            // Create a message for the response
            var msg = ex.InnerException?.Message ?? ex.Message;
            return Ok(new { Message = "Error: " + msg });
        }
    }
}


  • If you want to know more about the comparison of App service plans of windows and linux see the below table for your reference.
For developers who are still evaluating the framework itself, ASP.NET Core is commonly used for cloud-based applications, APIs, web apps, and backend services. You can also read more about the advantages of ASP.NET Core before finalizing your technology stack.
Note: The current sample uses older Azure Storage classes such asCloudStorageAccount.

Azure Linux vs Windows App Service for PDF Generation

The better App Service operating system depends on the application’s dependencies rather than one platform being universally better.

RequirementLinux App ServiceWindows App Service
ASP.NET Core hostingSupportedSupported
Native wkhtmltopdf deploymentPossiblePossible
Custom Linux containerYesNo
Windows-specific dependencyNot suitableBetter fit
Control of Linux system packagesStronger through containerNot applicable
Existing Windows applicationMay require changesOften easier
Font/dependency testingRequiredRequired

Choose Linux when

  • Your application supports Linux
  • You want to package native dependencies in a Linux container
  • wkhtmltopdf has been validated in your chosen Linux environment

Choose Windows when

  • The application already depends on Windows components
  • A Windows-specific executable or library is required
  • Migrating the application to Linux would introduce unnecessary complexity

The final decision should be based on the actual runtime dependencies and tested deployment environment.

Azure App Service Linux vs Windows Pricing for PDF Generation

App Service pricing varies by region, operating system, tier and billing configuration. Check Microsoft’s current Azure pricing information before making a hosting decision.

Should You Keep Using wkhtmltopdf in 2026?

For an existing application, wkhtmltopdf may still remain practical when the implementation is stable and thoroughly tested.

Replacing a working PDF engine can introduce new rendering differences, migration work and regression testing.

However, for a new application, the fact that wkhtmltopdf’s official repository is archived should form part of the technical decision.

Evaluate:

  • Maintenance status
  • Security expectations
  • HTML and CSS requirements
  • JavaScript rendering
  • Cloud deployment requirements
  • Support expectations
  • Migration risk
  • Long-term product roadmap

A new application with modern HTML/CSS or JavaScript-heavy templates may benefit from evaluating actively maintained browser-based or PDF-generation alternatives before adopting wkhtmltopdf.

Recommended PDF Generation Approach by Scenario

ScenarioRecommended Direction
Existing wkhtmltopdf implementation works reliablyKeep it and validate the deployment
Existing DinkToPDF app needs page numbersFix PagesCount/header/footer configuration
wkhtmltopdf fails only after Azure deploymentInvestigate environment before rewriting code
Native Linux dependencies are difficult to manageConsider a custom Linux container
Existing Windows-specific applicationEvaluate Windows App Service
New long-term applicationCompare actively maintained PDF engines
Large or complex PDF workloadConsider moving generation to background processing
Modern CSS/JavaScript templatesTest rendering compatibility before selecting the engine

Conclusion: Best PDF Generation Option for ASP.NET Core on Azure

Generating PDFs in ASP.NET Core on Azure requires more than selecting a .NET library.

You also need to account for:

  • Native dependencies
  • Operating system
  • Runtime architecture
  • Fonts
  • Azure hosting configuration
  • PDF complexity
  • Long-term maintenance

If an application already uses wkhtmltopdf or DinkToPDF, first determine whether the problem is in the PDF configuration or Azure environment before replacing the implementation.

For DinkToPDF page numbering, the key configuration is:


PagesCount = true

with placeholders such as:


Page [page] of [toPage]

If the same code works locally but fails on Azure, compare native libraries, operating system, architecture, fonts, resource availability and hosting restrictions.

For a new system, also consider wkhtmltopdf’s archived maintenance status before choosing it as a long-term dependency.

Need help with an ASP.NET Core or Azure implementation?

Satva Solutions can help assess your .NET application architecture, Azure deployment environment and integration requirements.

Talk to our Azure development team→

Frequently Asked Questions

Can I generate PDFs in ASP.NET Core on Azure App Service?

Yes. ASP.NET Core applications can generate PDFs on Azure App Service using tools such as wkhtmltopdf, DinkToPDF and Rotativa. However, native dependencies, operating system, architecture, fonts and hosting configuration can affect the deployment.

Does wkhtmltopdf work on Azure App Service?

Yes, wkhtmltopdf can work on Azure App Service, but the correct configuration depends on the operating system and runtime environment. If it works locally but fails after deployment, verify native binaries, architecture, fonts and hosting restrictions.

How do I use DinkToPDF in .NET Core?

Configure GlobalSettings and ObjectSettings, create an HtmlToPdfDocument, and pass it to the DinkToPDF converter. Because DinkToPDF uses wkhtmltopdf, the required native library must also be available.

How do I add page numbers in DinkToPDF?

Enable:


PagesCount = true

and use [page] and [toPage] inside HeaderSettings or FooterSettings.

Example:


FooterSettings =
{
    Right = "Page [page] of [toPage]"
}

What does [page] mean in DinkToPDF?

[page] represents the current PDF page number.

For example, on the fourth page:


Page [page]

can render as:


Page 4

What does [toPage] mean in DinkToPDF?

[toPage] represents the last page or total number of pages in the generated document.

For example:


Page [page] of [toPage]

can render as:


Page 4 of 12

Why is [toPage] not working in DinkToPDF?

Check that PagesCount = true is enabled. Also verify that [toPage] appears correctly inside HeaderSettings or FooterSettings and that the wkhtmltopdf native dependency is loading properly.

Why does PDF generation work locally but fail on Azure?

The local computer may already contain required fonts, libraries, permissions and resources. Azure App Service uses a different runtime environment, which can expose dependency, architecture or hosting limitations.

Why does DinkToPDF timeout on Azure?

Possible causes include native dependency problems, resource limitations, complex PDF content, inaccessible external assets or Azure configuration. Check application logs and dependency loading before assuming that upgrading the hosting tier is the only solution.

Can wkhtmltopdf run on Azure App Service Free Plan?

It can in some configurations. In Satva’s testing, a wkhtmltopdf implementation worked using an Azure Linux App Service Free configuration. That result should be treated as test-specific rather than guaranteed for every application.

Is Linux or Windows better for wkhtmltopdf on Azure?

Neither is universally better. Linux can be useful when applications support Linux or require custom Linux containers, while Windows can be preferable when the application depends on Windows-specific functionality.

Should I use a container for DinkToPDF or wkhtmltopdf?

A container can help when the application needs predictable native libraries, fonts and system dependencies. Azure App Service supports custom container deployments.

Is wkhtmltopdf still maintained?

The official wkhtmltopdf repository was archived on January 2, 2023 and is read-only. Existing applications may continue to use it, but new projects should consider its maintenance status during technology selection.




Article by

Chintan Prajapati

Chintan Prajapati is the Founder and CEO of Satva Solutions and a seasoned computer engineer with over two decades of experience in the software industry. His expertise spans Accounting & ERP Integrations, Robotic Process Automation, and the development of technology solutions built around leading ERP and accounting platforms with a particular focus on responsible AI and machine learning in fintech.Chintan holds a BE in Computer Engineering and carries an impressive roster of certifications, including Microsoft Certified Professional, Microsoft Certified Technology Specialist, Certified Azure Solution Developer, Certified Intuit Developer, Certified QuickBooks ProAdvisor, and Xero Developer.Over the course of his career, he has made a measurable impact on the accounting industry consulting on and delivering integration and automation solutions that have collectively saved thousands of man-hours. His writing aims to offer readers practical, insight-driven advice on harnessing technology to unlock greater business efficiency.When he steps away from the desk, Chintan can be found trekking through mountain trails or watching birds in the wild. Grounded in the philosophy of delivering the highest value to clients, he continues to champion innovation and excellence in digital transformation from his home base in Ahmedabad, India.