Passer au contenu du pied de page
GUIDES DE MIGRATION

Migration de Fluid (Templating) vers IronPDF

Fluid est une bibliothèque .NET qui implémente le langage de modèles Liquid, offrant aux développeurs une manière flexible de générer des modèles dynamiques et de séparer le contenu de la logique de présentation. Bien que Fluid soit efficace pour générer des sorties de texte dynamiques, il ne prend pas directement en charge la génération de PDF ; les développeurs doivent intégrer une bibliothèque PDF supplémentaire pour convertir la sortie HTML en documents PDF. Cette approche à deux bibliothèques introduit une complexité que de nombreuses équipes de développement cherchent à éliminer.

Ce guide fournit un chemin de migration complet de Fluid (templating) avec des bibliothèques PDF externes vers IronPDF, avec des instructions étape par étape, des comparaisons de code et des exemples pratiques pour les développeurs .NET professionnels qui évaluent cette transition.

Pourquoi migrer de Fluid (Templating) vers IronPDF

Fluid est un moteur de modèles solide basé sur Liquid, mais son utilisation pour la génération de PDF introduit une complexité importante :

Dépendance à deux bibliothèques : Fluid ne génère que du HTML ; vous avez besoin d'une bibliothèque PDF distincte (wkhtmltopdf, PuppeteerSharp, etc.) pour créer des PDF, ce qui double vos dépendances et votre charge de maintenance.

Complexité de l'intégration : coordonner deux bibliothèques implique de gérer deux ensembles de configurations, de gestion des erreurs et de mises à jour. Lorsque quelque chose se casse, le débogage devient plus difficile.

Courbe d'apprentissage de la syntaxe Liquid : les développeurs doivent apprendre la syntaxe de modèle Liquid ( {{ }} , {% %} ) alors que C# possède déjà de puissantes capacités de gestion de chaînes intégrées.

Contrôle limité des PDF : la qualité de vos fichiers PDF dépend de la bibliothèque PDF que vous choisissez d'associer à Fluid, et non d'un moteur de rendu dédié.

Difficultés de débogage : des erreurs peuvent survenir lors de la création des modèles ou de la génération des PDF, ce qui rend le dépannage plus difficile qu'avec une solution intégrée unique.

Problèmes de sécurité liés aux threads : TemplateContextn'est pas sûr en matière de threads et nécessite une gestion attentive dans les applications concurrentes.

IronPDFvs Fluid (Templating) : Comparaison des fonctionnalités

La compréhension des différences architecturales aide les décideurs techniques à évaluer l'investissement dans la migration :

Aspect Bibliothèque Fluid + PDF IronPDF
Dépendances 2+ packages (Fluid + bibliothèque PDF) Paquet unique
Templir Syntaxe liquide ({{ }}) Interpolation de chaînes de caractères en C# ou Razor
Génération de PDF Bibliothèque externe requise Moteur Chromium intégré
Support CSS Dépend de la bibliothèque PDF CSS3 complet avec Flexbox/Grid
JavaScript Dépend de la bibliothèque PDF Prise en charge complète de JavaScript
Sécurité des threads TemplateContext n'est pas sûr pour les threads ChromePdfRenderer est sûr pour les threads
Courbe d'apprentissage Bibliothèque Liquid + PDF API HTML/CSS (normes web)
Gestion des erreurs Deux sources d'erreurs Une seule source d'erreur

Démarrage rapide : Migration de Fluid vers IronPDF

La migration peut commencer immédiatement grâce à ces étapes fondamentales.

Étape 1 : Remplacer les paquets NuGet

Supprimez Fluid et toute bibliothèque PDF externe :

# Remove Fluid and external PDF library
dotnet remove package Fluid.Core
dotnet remove package WkHtmlToPdf-DotNet  # or whatever PDF library you used
dotnet remove package PuppeteerSharp       # if used
# Remove Fluid and external PDF library
dotnet remove package Fluid.Core
dotnet remove package WkHtmlToPdf-DotNet  # or whatever PDF library you used
dotnet remove package PuppeteerSharp       # if used
SHELL

InstallezIronPDF:

# InstallIronPDF(all-in-one solution)
dotnet add package IronPdf
# InstallIronPDF(all-in-one solution)
dotnet add package IronPdf
SHELL

Étape 2 : Mise à jour des espaces de noms

Remplacez les espaces de noms Fluid par IronPdf :

// Before (Fluid + external PDF library)
using Fluid;
using Fluid.Values;
using SomeExternalPdfLibrary;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;  // For RenderingOptions
// Before (Fluid + external PDF library)
using Fluid;
using Fluid.Values;
using SomeExternalPdfLibrary;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;  // For RenderingOptions
$vbLabelText   $csharpLabel

Étape 3 : initialisation de la licence

Ajouter l'initialisation de la licence au démarrage de l'application :

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Exemples de migration de code

Les bases du HTML au PDF

L'opération la plus fondamentale révèle la différence essentielle entre ces approches.

Approche fluide:

// NuGet: Install-Package Fluid.Core
using Fluid;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var parser = new FluidParser();
        var template = parser.Parse("<html><body><h1>Hello {{name}}!</h1></body></html>");
        var context = new TemplateContext();
        context.SetValue("name", "World");
        var html = await template.RenderAsync(context);

        // Fluid only generates HTML - you'd need another library to convert to PDF
        File.WriteAllText("output.html", html);
    }
}
// NuGet: Install-Package Fluid.Core
using Fluid;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var parser = new FluidParser();
        var template = parser.Parse("<html><body><h1>Hello {{name}}!</h1></body></html>");
        var context = new TemplateContext();
        context.SetValue("name", "World");
        var html = await template.RenderAsync(context);

        // Fluid only generates HTML - you'd need another library to convert to PDF
        File.WriteAllText("output.html", html);
    }
}
$vbLabelText   $csharpLabel

Approche IronPDF:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var html = "<html><body><h1>Hello World!</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var html = "<html><body><h1>Hello World!</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

Fluid nécessite la création d'un FluidParser, l'analyse de la chaîne du modèle, la création d'un TemplateContext, l'appel à SetValue() pour chaque variable, le rendu asynchrone pour obtenir du HTML, puis l'écriture dans un fichier - qui n'est toujours pas un PDF. Le commentaire dans le code indique explicitement que "Fluid ne génère que du HTML - vous aurez besoin d'une autre bibliothèque pour convertir en PDF"

IronPDF élimine cette complexité : créez un moteur de rendu, appelez RenderHtmlAsPdf(), et enregistrez directement au format PDF. Pas de fichiers HTML intermédiaires, pas de bibliothèques supplémentaires.

Pour les scénarios avancés de conversion de HTML en PDF, voir le guide de conversion de HTML en PDF.

Modèle de facture avec données dynamiques

Les modèles de documents comportant plusieurs variables montrent clairement les différences de modèles.

Approche fluide:

// NuGet: Install-Package Fluid.Core
using Fluid;
using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var parser = new FluidParser();
        var template = parser.Parse(@"
            <html><body>
                <h1>Invoice #{{invoiceNumber}}</h1>
                <p>Date: {{date}}</p>
                <p>Customer: {{customer}}</p>
                <p>Total: ${{total}}</p>
            </body></html>");

        var context = new TemplateContext();
        context.SetValue("invoiceNumber", "12345");
        context.SetValue("date", DateTime.Now.ToShortDateString());
        context.SetValue("customer", "John Doe");
        context.SetValue("total", 599.99);

        var html = await template.RenderAsync(context);
        // Fluid outputs HTML - requires additional PDF library
        File.WriteAllText("invoice.html", html);
    }
}
// NuGet: Install-Package Fluid.Core
using Fluid;
using System;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var parser = new FluidParser();
        var template = parser.Parse(@"
            <html><body>
                <h1>Invoice #{{invoiceNumber}}</h1>
                <p>Date: {{date}}</p>
                <p>Customer: {{customer}}</p>
                <p>Total: ${{total}}</p>
            </body></html>");

        var context = new TemplateContext();
        context.SetValue("invoiceNumber", "12345");
        context.SetValue("date", DateTime.Now.ToShortDateString());
        context.SetValue("customer", "John Doe");
        context.SetValue("total", 599.99);

        var html = await template.RenderAsync(context);
        // Fluid outputs HTML - requires additional PDF library
        File.WriteAllText("invoice.html", html);
    }
}
$vbLabelText   $csharpLabel

Approche IronPDF:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var invoiceNumber = "12345";
        var date = DateTime.Now.ToShortDateString();
        var customer = "John Doe";
        var total = 599.99;

        var html = $@"
            <html><body>
                <h1>Invoice #{invoiceNumber}</h1>
                <p>Date: {date}</p>
                <p>Customer: {customer}</p>
                <p>Total: ${total}</p>
            </body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("invoice.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var invoiceNumber = "12345";
        var date = DateTime.Now.ToShortDateString();
        var customer = "John Doe";
        var total = 599.99;

        var html = $@"
            <html><body>
                <h1>Invoice #{invoiceNumber}</h1>
                <p>Date: {date}</p>
                <p>Customer: {customer}</p>
                <p>Total: ${total}</p>
            </body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("invoice.pdf");
    }
}
$vbLabelText   $csharpLabel

Fluid utilise la syntaxe {{variable}} de Liquid avec context.SetValue() pour chaque variable. Le commentaire indique explicitement que "Fluid produit du HTML - nécessite une bibliothèque PDF supplémentaire"IronPDFutilise l'interpolation de chaîne C# standard ($"{variable}")-syntaxe que les développeurs connaissent déjà- et produit directement au format PDF.

Explorez les tutoriels IronPDF pour découvrir d'autres modèles de génération de documents.

Données dynamiques avec des boucles

Des modèles avec des collections et des boucles démontrent les différences de flux de contrôle.

Approche fluide:

// NuGet: Install-Package Fluid.Core
using Fluid;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var parser = new FluidParser();
        var template = parser.Parse(@"
            <html><body>
                <h1>{{title}}</h1>
                <ul>
                {% for item in items %}
                    <li>{{item}}</li>
                {% endfor %}
                </ul>
            </body></html>");

        var context = new TemplateContext();
        context.SetValue("title", "My List");
        context.SetValue("items", new[] { "Item 1", "Item 2", "Item 3" });

        var html = await template.RenderAsync(context);
        // Fluid generates HTML only - separate PDF conversion needed
        File.WriteAllText("template-output.html", html);
    }
}
// NuGet: Install-Package Fluid.Core
using Fluid;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var parser = new FluidParser();
        var template = parser.Parse(@"
            <html><body>
                <h1>{{title}}</h1>
                <ul>
                {% for item in items %}
                    <li>{{item}}</li>
                {% endfor %}
                </ul>
            </body></html>");

        var context = new TemplateContext();
        context.SetValue("title", "My List");
        context.SetValue("items", new[] { "Item 1", "Item 2", "Item 3" });

        var html = await template.RenderAsync(context);
        // Fluid generates HTML only - separate PDF conversion needed
        File.WriteAllText("template-output.html", html);
    }
}
$vbLabelText   $csharpLabel

Approche IronPDF:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var title = "My List";
        var items = new[] { "Item 1", "Item 2", "Item 3" };

        var html = $@"
            <html><body>
                <h1>{title}</h1>
                <ul>";

        foreach (var item in items)
        {
            html += $"<li>{item}</li>";
        }

        html += "</ul></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("template-output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var title = "My List";
        var items = new[] { "Item 1", "Item 2", "Item 3" };

        var html = $@"
            <html><body>
                <h1>{title}</h1>
                <ul>";

        foreach (var item in items)
        {
            html += $"<li>{item}</li>";
        }

        html += "</ul></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("template-output.pdf");
    }
}
$vbLabelText   $csharpLabel

Fluid utilise la syntaxe de Liquid {% for item in items %}...{% endfor %}, un langage de templage que les développeurs doivent apprendre. Le commentaire indique que "Fluid génère uniquement du HTML - une conversion PDF séparée est nécessaire"IronPDFutilise des boucles foreach C# standard - aucune nouvelle syntaxe à apprendre - et produit des sorties directement au format PDF.

Référence de mappage de l'API fluide vers IronPDF

Cette cartographie accélère la migration en indiquant les équivalents directs des API :

Mappage des classes de base

Classe Fluide Équivalent d'IronPDF Notes
FluidParser N/A Inutile : utilisez des chaînes de caractères C#
FluidTemplate N/A Pas nécessaire
TemplateContext Objets/chaînes C# Transmettre des données directement
Options de modèle Options de rendu Configuration de la sortie PDF
ValeurFluide Types de C# natifs Aucune conversion nécessaire
Classe PDF externe ChromePdfRenderer Classe de rendu principale

Mise en correspondance des méthodes

Méthode fluide Équivalent d'IronPDF Notes
new FluidParser() new ChromePdfRenderer() Créer un moteur de rendu à la place
parser.Parse(source) N/A Pas nécessaire - le HTML est une chaîne de caractères
template.RenderAsync(context) renderer.RenderHtmlAsPdf(html) Rendu PDF direct
context.SetValue("key", value) var clé = valeur; Utiliser des variables C#

Mappage de la syntaxe liquide vers C

Syntaxe de Liquid Équivalent en C# Notes
{{ variable }} $"{variable}" Interpolation de chaînes de caractères
{% for item in items %} foreach (var item in items) Boucle C#
{% if condition %} si (condition) C# conditionnel
{{ x \| upcase }} x.ToUpper() Méthode C#
{{ x \| date : '%Y-%m-%d' }} x.ToString("yyyy-MM-dd") Formatage C#
{{ x \| number_with_precision : 2 }} x.ToString("F2") Formatage des nombres en C#

Problèmes de migration courants et solutions

Édition 1 : Conversion de la syntaxe liquide

Fluid: Utilise la syntaxe {{ variable }}et {% contrôle %}.

Solution: Remplacer par l'interpolation de chaînes de caractères et le flux de contrôle en C# :

// Liquid: {{ name | upcase }}
// C#: $"{name.ToUpper()}"

// Liquid: {% for item in items %}{{item}}{% endfor %}
// C#: foreach (var item in items) { html += $"{item}"; }
// Liquid: {{ name | upcase }}
// C#: $"{name.ToUpper()}"

// Liquid: {% for item in items %}{{item}}{% endfor %}
// C#: foreach (var item in items) { html += $"{item}"; }
$vbLabelText   $csharpLabel

Edition 2 : Variables TemplateContext

Fluid: Utilise context.SetValue("key", value)pour transmettre des données.

Solution: Utilisez des variables C# standard :

// Before (Fluid)
var context = new TemplateContext();
context.SetValue("customer", customerName);

// After (IronPDF)
var customer = customerName;
var html = $"<p>Customer: {customer}</p>";
// Before (Fluid)
var context = new TemplateContext();
context.SetValue("customer", customerName);

// After (IronPDF)
var customer = customerName;
var html = $"<p>Customer: {customer}</p>";
$vbLabelText   $csharpLabel

Numéro 3 : Thread Safety

Fluid: TemplateContextn'est pas à l'abri des threads, ce qui nécessite une gestion prudente dans les applications concurrentes.

Solution: ChromePdfRendererest à l'abri des threads et peut être partagé entre plusieurs threads :

// Thread-safe usage
private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();

public byte[] GeneratePdf(string html)
{
    var pdf = _renderer.RenderHtmlAsPdf(html);
    return pdf.BinaryData;
}
// Thread-safe usage
private static readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();

public byte[] GeneratePdf(string html)
{
    var pdf = _renderer.RenderHtmlAsPdf(html);
    return pdf.BinaryData;
}
$vbLabelText   $csharpLabel

Edition 4 : Traitement des erreurs en deux étapes

Fluide: Des erreurs peuvent se produire à l'étape de la mise en page OU à l'étape de la génération du PDF.

Solution:IronPDFa une seule source d'erreur :

try
{
    var pdf = renderer.RenderHtmlAsPdf(html);
    pdf.SaveAs("output.pdf");
}
catch (Exception ex)
{
    // Single point of failure—easier debugging
    Console.WriteLine($"PDF generation failed: {ex.Message}");
}
try
{
    var pdf = renderer.RenderHtmlAsPdf(html);
    pdf.SaveAs("output.pdf");
}
catch (Exception ex)
{
    // Single point of failure—easier debugging
    Console.WriteLine($"PDF generation failed: {ex.Message}");
}
$vbLabelText   $csharpLabel

Liste de contrôle de la migration des fluides

Tâches préalables à la migration

Auditez votre base de code pour identifier toutes les utilisations de Fluid :

# Find all Fluid references
grep -r "FluidParser\|FluidTemplate\|TemplateContext\|using Fluid" --include="*.cs" --include="*.csproj" .

# Find Liquid template files
find . -name "*.liquid" -o -name "*.html" | xargs grep -l "{{"
# Find all Fluid references
grep -r "FluidParser\|FluidTemplate\|TemplateContext\|using Fluid" --include="*.cs" --include="*.csproj" .

# Find Liquid template files
find . -name "*.liquid" -o -name "*.html" | xargs grep -l "{{"
SHELL

Documentez tous les modèles : emplacements des fichiers, variables utilisées, boucles et conditionnelles, et configuration de la bibliothèque PDF externe.

Tâches de mise à jour du code

  1. Supprimer le paquet NuGet Fluid.Core
  2. Suppression d'une bibliothèque PDF externe
  3. Installer le paquet NuGet IronPdf
  4. Mise à jour des importations de l'espace de noms de Fluid vers IronPdf
  5. Convertir {{ variable }}en $"{variable}"
  6. Convertir {% for item in collection %} en foreach en C#
  7. Convertir les {% if condition %}en déclarations if en C#
  8. Convertir les filtres Liquid en méthodes C# (par exemple, | upcase.ToUpper())
  9. Remplacer FluidParserpar ChromePdfRenderer
  10. Remplacer TemplateContext.SetValue() par des variables C# directes
  11. Supprimer les appels à la bibliothèque PDF externe
  12. Ajouter l'initialisation de la licenceIronPDFau démarrage

Test de post-migration

Après la migration, vérifiez ces aspects :

  • Vérifier que la sortie PDF correspond aux attentes
  • Testez le bon rendu de toutes les variantes du modèle
  • Vérifier que les images et le style s'affichent correctement
  • Valider que les sauts de page se produisent correctement
  • Test avec différentes tailles de données
  • Test de performance vs Fluid + bibliothèque externe
  • Tester la sécurité des threads dans des scénarios concurrents

Tâches de nettoyage

  • Supprimer les fichiers modèles .liquid (s'ils ne sont plus nécessaires)
  • Suppression du code d'aide lié à Fluid
  • Mise à jour de la documentation
  • Nettoyer les dépendances inutilisées

Avantages clés de la migration vers IronPDF

Passer de Fluid (templating) avec des bibliothèques PDF externes àIronPDFoffre plusieurs avantages cruciaux :

Solution à package unique : éliminez la dépendance à deux bibliothèques.IronPDFgère à la fois la création de modèles (via HTML/CSS) et la génération de PDF dans un seul et même package.

Aucune nouvelle syntaxe à apprendre : utilisez l'interpolation de chaînes et le flux de contrôle standard de C# au lieu d'apprendre la syntaxe des modèles Liquid.

Rendu multithread sécurisé : ChromePdfRendererest multithread sécurisé, contrairement à TemplateContext, ce qui simplifie la génération simultanée de PDF.

Moteur de rendu Chromium : Le rendu conforme aux normes de l'industrie assure une prise en charge complète de CSS3, y compris Flexbox et Grid, ainsi qu'une exécution JavaScript complète.

Source d'erreur unique : le débogage est simplifié grâce à une seule bibliothèque à dépanner, au lieu de devoir coordonner les étapes de création de modèles et de génération de PDF.

Développement actif : Avec l'adoption croissante de .NET 10 et C# 14 jusqu'en 2026, les mises à jour régulières d'IronPDF garantissent la compatibilité avec les versions actuelles et futures de .NET.

Curtis Chau
Rédacteur technique

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes ...

Lire la suite