Saltar al pie de página
GUíAS DE MIGRACIóN

Migración de Fluid (Templating) a IronPDF

Fluid es una biblioteca .NET que implementa el lenguaje de plantillas Liquid, ofreciendo a los desarrolladores una forma flexible de renderizar plantillas dinámicas y separar el contenido de la lógica de presentación. Si bien Fluid es eficaz para generar salidas de texto dinámicas, no admite directamente la generación de PDF: los desarrolladores deben integrar una biblioteca PDF adicional para convertir la salida HTML en documentos PDF. Este enfoque de dos bibliotecas introduce una complejidad que muchos equipos de desarrollo tratan de eliminar.

Esta guía proporciona una ruta de migración completa de Fluid (plantillas) con bibliotecas PDF externas a IronPDF, con instrucciones paso a paso, comparaciones de código y ejemplos prácticos para desarrolladores .NET profesionales que evalúan esta transición.

Por qué migrar de Fluid (Templating) a IronPDF

Fluid es un motor de plantillas sólido basado en Liquid, pero su uso para la generación de PDF introduce una complejidad significativa:

Dependencia de dos bibliotecas: Fluid solo genera HTML; necesita una biblioteca PDF separada (wkhtmltopdf, PuppeteerSharp, etc.) para crear archivos PDF, lo que duplica sus dependencias y la carga de mantenimiento.

Complejidad de integración: coordinar dos bibliotecas significa administrar dos conjuntos de configuraciones, manejo de errores y actualizaciones. Cuando algo se rompe, la depuración se convierte en todo un reto.

Curva de aprendizaje de sintaxis líquida: los desarrolladores deben aprender la sintaxis de plantillas de Liquid ( {{ }} , {% %} ) cuando C# ya tiene incorporadas potentes capacidades de manejo de cadenas.

Control de PDF limitado: la calidad de salida de PDF depende de la biblioteca de PDF que elija para combinar con Fluid, no de un motor de renderizado dedicado.

Desafíos de depuración: pueden ocurrir errores tanto en la etapa de creación de plantillas como en la de generación de PDF, lo que hace que la resolución de problemas sea más difícil que con una única solución integrada.

Preocupaciones sobre la seguridad de los subprocesos: <código>TemplateContext</códigono es seguro para subprocesos y requiere una gestión cuidadosa en aplicaciones concurrentes.

IronPDFfrente a Fluid (Templating): Comparación de características

Comprender las diferencias arquitectónicas ayuda a los responsables técnicos a evaluar la inversión en migración:

AspectoBiblioteca Fluid + PDFIronPDF
Dependencias2+ paquetes (Fluid + biblioteca PDF)Paquete único
PlanificaciónSintaxis líquida ({{ }})Interpolación de cadenas en C# o Razor
Generación de PDFBiblioteca externa necesariaMotor Chromium integrado
Soporte CSSDepende de la biblioteca PDFCSS3 completo con Flexbox/Grid
JavaScriptDepende de la biblioteca PDFCompatibilidad total con JavaScript
Seguridad de hilosTemplateContext no es thread-safeChromePdfRenderer es a prueba de hilos
Curva de aprendizajeAPI de la biblioteca Liquid + PDFHTML/CSS (estándares web)
Manejo de erroresDos fuentes de errorFuente de error única

Inicio rápido: Migración de Fluid a IronPDF

La migración puede comenzar inmediatamente con estos pasos básicos.

Paso 1: Sustituir paquetes NuGet

Elimine Fluid y cualquier biblioteca PDF externa:

# 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

Instalar IronPDF:

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

Paso 2: Actualizar los espacios de nombres

Sustituya los espacios de nombres Fluid por 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

Paso 3: Inicializar licencia

Añadir inicialización de licencia al inicio de la aplicación:

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

Ejemplos de migración de código

HTML básico a PDF

La operación más fundamental revela la diferencia clave entre estos enfoques.

Enfoque fluido:

// 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

Enfoque 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 requiere crear un FluidParser, analizar la cadena de plantilla, crear un TemplateContext, llamar a SetValue() para cada variable, renderizar de forma asíncrona para obtener HTML y, a continuación, escribir en un archivo, que todavía no es un PDF. El comentario en el código dice explícitamente "Fluid sólo genera HTML - necesitarías otra librería para convertir a PDF."

IronPDF elimina esta complejidad: cree un renderizador, llame a RenderHtmlAsPdf() y guarde directamente en PDF. Sin archivos HTML intermedios ni bibliotecas adicionales.

Para situaciones avanzadas de conversión de HTML a PDF, consulte la Guía de conversión de HTML a PDF.

Plantilla de factura con datos dinámicos

Las plantillas de documentos con múltiples variables muestran claramente las diferencias en el patrón de plantillas.

Enfoque fluido:

// 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

Enfoque 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 utiliza la sintaxis {{variable}} de Liquid con context.SetValue() para cada variable. El comentario señala explícitamente "Fluid produce HTML - requiere una biblioteca PDF adicional"IronPDFutiliza la interpolación de cadenas estándar de C# ($"{variable}") -sintaxis que los desarrolladores ya conocen- y genera directamente PDF.

Explore los tutoriales IronPDF para conocer más patrones de generación de documentos.

Datos dinámicos con bucles

Las plantillas con colecciones y bucles demuestran las diferencias en el flujo de control.

Enfoque fluido:

// 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

Enfoque 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 utiliza la sintaxis {% for item in items %}...{% endfor %} de Liquid, un lenguaje de plantillas que los desarrolladores deben aprender. En el comentario se indica que "Fluid solo genera HTML; se necesita una conversión a PDF por separado"IronPDFutiliza bucles foreach estándar de C# -no hay que aprender una nueva sintaxis- y genera directamente archivos PDF.

Referencia de mapeo de Fluid API a IronPDF

Este mapeo acelera la migración al mostrar los equivalentes directos de las API:

Mapeo de clases principales

Clase FluidEquivalente de IronPDFNotas
<código>FluidParser</códigoN/ANo es necesario utilizar cadenas de C#
<código>FluidTemplate</códigoN/ANo es necesario
<código>TemplateContext</códigoObjetos/cadenas de C#Pasar datos directamente
Opciones de plantilla<código>RenderingOptions</códigoConfiguración de salida PDF
<código>FluidValue</códigoTipos nativos de C#No se necesita conversión
Clase de PDF externo<código>ChromePdfRenderer</códigoClase principal de renderización

Métodos

Método FluidEquivalente de IronPDFNotas
nuevo FluidParser()<código>new ChromePdfRenderer()</códigoCrear renderizador en su lugar
parser.Parse(source)N/ANo es necesario-HTML es una cadena
<código>template.RenderAsync(context)</códigorenderer.RenderHtmlAsPdf(html)Representación directa en PDF
<código>context.SetValue("clave", valor)</códigovar clave = valor;Uso de variables de C#

Mapeo de sintaxis líquida a C

Sintaxis líquidaEquivalente de C#Notas
{{ variable }}$"{variable}"Interpolación de cadenas
{% for item in items %}foreach (var item in items)Bucle C#
{% if condition %}if (condición)C# condicional
{{ x \| mayúsculas }}x.ToUpper()Método C#
{{ x \| date: '%Y-%m-%d' }}x.ToString("aaaa-MM-dd")Formato en C#
{{ x \| número_con_precisión: 2 }}<código>x.ToString("F2")</códigoFormato de números en C#

Problemas comunes de migración y soluciones

Número 1: Conversión de sintaxis líquida

Fluid: Utiliza la sintaxis {{ variable }}y {% control %}.

Solución: Sustituir por interpolación de cadenas y flujo de control 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

Número 2: Variables TemplateContext

Fluid: Utiliza <código>context.SetValue("clave", valor)</códigopara pasar datos.

Solución: Utilizar variables estándar de C#:

// 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

Número 3: Seguridad de hilos

Fluid: <código>TemplateContext</códigono es seguro para hilos, por lo que requiere una gestión cuidadosa en aplicaciones concurrentes.

Solución: <código>ChromePdfRenderer</códigoes seguro para subprocesos y se puede compartir entre subprocesos:

// 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

Número 4: Tratamiento de errores en dos fases

Fluid: Pueden producirse errores en la fase de creación de plantillas O en la fase de generación de PDF.

Solución:IronPDFtiene una única fuente de error:

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

Lista de comprobación de migración de fluidos

Tareas previas a la migración

Audite su código base para identificar todo el uso 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

Documente todas las plantillas: ubicaciones de archivos, variables utilizadas, bucles y condicionales, y configuración de bibliotecas PDF externas.

Tareas de actualización de código

  1. Eliminar el paquete NuGet de Fluid.Core
  2. Eliminar el paquete de bibliotecas PDF externas
  3. Instalación del paquete IronPdf NuGet
  4. Actualizar las importaciones de espacios de nombres de Fluid a IronPdf
  5. Convertir {{ variable }}a $"{variable}"
  6. Convertir {% for item in collection %} a foreach de C#
  7. Convertir {% if condition %}en sentencias if de C#
  8. Convierta los filtros de Liquid en métodos de C# (por ejemplo, | mayúsculas y minúsculas.ToUpper())
  9. Sustituya <código>FluidParser</códigopor ChromePdfRenderer
  10. Sustituir TemplateContext.SetValue() por variables directas de C#
  11. Eliminar las llamadas a bibliotecas PDF externas
  12. Añadir la inicialización de la licenciaIronPDFal inicio

Pruebas posteriores a la migración

Tras la migración, verifique estos aspectos:

  • Verificación de que el resultado PDF se ajusta a las expectativas
  • Pruebe que todas las variaciones de la plantilla se muestran correctamente
  • Compruebe que las imágenes y el estilo se muestran correctamente
  • Validar que los saltos de página se produzcan correctamente
  • Prueba con varios tamaños de datos
  • Pruebas de rendimiento frente a Fluid + biblioteca externa
  • Pruebe la seguridad de los subprocesos en escenarios concurrentes

Tareas de limpieza

  • Eliminar los archivos de plantilla .liquid (si ya no son necesarios)
  • Eliminar el código de ayuda relacionado con Fluid
  • Actualización de la documentación
  • Limpiar dependencias no utilizadas

Beneficios clave de migrar a IronPDF

Pasar de Fluid (creación de plantillas) con bibliotecas PDF externas aIronPDFofrece varias ventajas fundamentales:

Solución de paquete único: eliminar la dependencia de dos bibliotecas.IronPDFse encarga tanto de la creación de plantillas (mediante HTML/CSS) como de la generación de PDF en un solo paquete.

No hay ninguna sintaxis nueva que aprender: utilice la interpolación de cadenas y el flujo de control de C# estándar en lugar de aprender la sintaxis de plantillas de Liquid.

Representación segura para subprocesos: <código>ChromePdfRenderer</códigoes seguro para subprocesos, a diferencia de <código>TemplateContext</código, lo que simplifica la generación simultánea de PDF.

Motor de renderizado Chromium: la renderización estándar de la industria garantiza compatibilidad total con CSS3, incluidos Flexbox y Grid, además de ejecución completa de JavaScript.

Fuente de error única: la depuración se vuelve más sencilla con una sola biblioteca para solucionar problemas en lugar de coordinar entre las etapas de creación de plantillas y generación de PDF.

Desarrollo activo: a medida que aumenta la adopción de .NET 10 y C# 14 hasta 2026, las actualizaciones periódicas deIronPDFgarantizan la compatibilidad con las versiones actuales y futuras de .NET.

Curtis Chau
Escritor Técnico

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien ...

Leer más