푸터 콘텐츠로 바로가기
MIGRATION GUIDES

How to Migrate from BitMiracle Docotic PDF to IronPDF in C#

BitMiracle Docotic PDF is a well-regarded .NET PDF library known for its 100% managed code architecture and extensive programmatic PDF manipulation capabilities. However, its modular add-on structure—requiring separate packages for HTML-to-PDF conversion, layout features, and other functionality—adds complexity to project management and licensing. This comprehensive guide provides a step-by-step migration path from BitMiracle Docotic PDF to IronPDF—a unified .NET PDF library with built-in Chromium-based HTML rendering and all features included in a single NuGet package.

Why Migrate from BitMiracle Docotic PDF to IronPDF?

While BitMiracle Docotic PDF offers robust PDF manipulation features, several factors drive development teams to seek alternatives with more streamlined architecture.

Package Architecture Comparison

BitMiracle Docotic PDF uses a modular add-on approach that requires multiple packages for full functionality:

Aspect BitMiracle Docotic PDF IronPDF
HTML-to-PDF Requires separate add-on (HtmlToPdf) Built-in core feature
Package Structure Core + multiple add-ons Single NuGet package
Licensing Model Per-add-on licensing All features included
API Complexity Separate namespaces per add-on Unified API
HTML Engine Chromium (via add-on) Chromium (built-in)
Community Size Smaller Larger, more resources
Documentation Technical reference Extensive tutorials

Feature Parity

Both libraries support comprehensive PDF functionality:

Feature BitMiracle Docotic PDF IronPDF
Create PDF from scratch
HTML to PDF ✅ (add-on required) ✅ (built-in)
URL to PDF ✅ (add-on required) ✅ (built-in)
PDF manipulation
Text extraction
Merge/Split
Digital signatures
Encryption
Form filling
PDF/A compliance

Key Differences in Approach

BitMiracle Docotic PDF uses canvas-based drawing with coordinate positioning (canvas.DrawString(x, y, text)), while IronPDF leverages HTML/CSS for layout and positioning. This represents a paradigm shift that simplifies content creation for developers familiar with web technologies.

Pre-Migration Preparation

Prerequisites

Ensure your environment meets these requirements:

  • .NET Framework 4.6.2+ or .NET Core 3.1 / .NET 5-9
  • Visual Studio 2019+ or VS Code with C# extension
  • NuGet Package Manager access
  • IronPDF license key (free trial available at ironpdf.com)

Audit BitMiracle Docotic PDF Usage

Run these commands in your solution directory to identify all Docotic.Pdf references:

# Find all Docotic.Pdf usages in your codebase
grep -r "using BitMiracle.Docotic" --include="*.cs" .
grep -r "PdfDocument\|PdfPage\|PdfCanvas" --include="*.cs" .

# Find NuGet package references
grep -r "Docotic.Pdf" --include="*.csproj" .
# Find all Docotic.Pdf usages in your codebase
grep -r "using BitMiracle.Docotic" --include="*.cs" .
grep -r "PdfDocument\|PdfPage\|PdfCanvas" --include="*.cs" .

# Find NuGet package references
grep -r "Docotic.Pdf" --include="*.csproj" .
SHELL

Breaking Changes to Anticipate

Change BitMiracle Docotic PDF IronPDF Impact
HTML rendering Requires HtmlToPdf add-on Built-in Remove add-on package
Page indexing 0-based (Pages[0]) 0-based (Pages[0]) No change needed
Coordinate system Bottom-left origin HTML/CSS flow Use CSS for positioning
Canvas drawing PdfCanvas.DrawText() HTML markup Paradigm shift
Text extraction page.GetText() pdf.ExtractAllText() Method name change
Document loading new PdfDocument(path) PdfDocument.FromFile(path) Constructor → static method
Saving document.Save(path) pdf.SaveAs(path) Method name change
Disposal IDisposable pattern Not required Simpler resource management

Step-by-Step Migration Process

Step 1: Update NuGet Packages

Remove BitMiracle Docotic PDF packages and install IronPDF:

# Remove Docotic.Pdf packages
dotnet remove package BitMiracle.Docotic.Pdf
dotnet remove package BitMiracle.Docotic.Pdf.HtmlToPdf
dotnet remove package BitMiracle.Docotic.Pdf.Layout

# Install IronPDF
dotnet add package IronPdf
# Remove Docotic.Pdf packages
dotnet remove package BitMiracle.Docotic.Pdf
dotnet remove package BitMiracle.Docotic.Pdf.HtmlToPdf
dotnet remove package BitMiracle.Docotic.Pdf.Layout

# Install IronPDF
dotnet add package IronPdf
SHELL

Step 2: Update Namespace References

Replace BitMiracle Docotic PDF namespaces with IronPDF:

// Remove these
using BitMiracle.Docotic.Pdf;
using BitMiracle.Docotic.Pdf.Layout;
using BitMiracle.Docotic.Pdf.HtmlToPdf;

// Add this
using IronPdf;
// Remove these
using BitMiracle.Docotic.Pdf;
using BitMiracle.Docotic.Pdf.Layout;
using BitMiracle.Docotic.Pdf.HtmlToPdf;

// Add this
using IronPdf;
$vbLabelText   $csharpLabel

Step 3: Configure License

// Add at application startup (Program.cs or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Complete API Migration Reference

Document Operations

Task BitMiracle Docotic PDF IronPDF
Create empty document new PdfDocument() new PdfDocument()
Load from file new PdfDocument(path) PdfDocument.FromFile(path)
Load from stream PdfDocument.Load(stream) PdfDocument.FromStream(stream)
Load from bytes PdfDocument.Load(bytes) PdfDocument.FromBinaryData(bytes)
Save to file document.Save(path) pdf.SaveAs(path)
Get page count document.PageCount pdf.PageCount
Close/Dispose document.Dispose() Not required

HTML to PDF Conversion

Task BitMiracle Docotic PDF (HtmlToPdf Add-on) IronPDF
HTML string to PDF HtmlConverter.Create(html).ToPdf() renderer.RenderHtmlAsPdf(html)
HTML file to PDF HtmlConverter.Create(new Uri(filePath)).ToPdf() renderer.RenderHtmlFileAsPdf(path)
URL to PDF HtmlConverter.Create(new Uri(url)).ToPdf() renderer.RenderUrlAsPdf(url)
Set page size options.PageSize = PageSize.A4 renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
Set margins options.PageMargins = new Margins(20) renderer.RenderingOptions.MarginTop = 20

Merge and Split Operations

Task BitMiracle Docotic PDF IronPDF
Merge documents doc1.Append(doc2) PdfDocument.Merge(pdf1, pdf2)
Split document document.CopyPage(index) to new doc pdf.CopyPages(start, end)

Code Migration Examples

HTML to PDF Conversion

The most common operation demonstrates the significant simplification IronPDF provides.

BitMiracle Docotic PDF Implementation:

// NuGet: Install-Package Docotic.Pdf
using BitMiracle.Docotic.Pdf;
using System;

class Program
{
    static void Main()
    {
        using (var pdf = new PdfDocument())
        {
            string html = "<html><body><h1>Hello World</h1><p>This is HTML to PDF conversion.</p></body></html>";

            pdf.CreatePage(html);
            pdf.Save("output.pdf");
        }

        Console.WriteLine("PDF created successfully");
    }
}
// NuGet: Install-Package Docotic.Pdf
using BitMiracle.Docotic.Pdf;
using System;

class Program
{
    static void Main()
    {
        using (var pdf = new PdfDocument())
        {
            string html = "<html><body><h1>Hello World</h1><p>This is HTML to PDF conversion.</p></body></html>";

            pdf.CreatePage(html);
            pdf.Save("output.pdf");
        }

        Console.WriteLine("PDF created successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF Implementation:

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        string html = "<html><body><h1>Hello World</h1><p>This is HTML to PDF conversion.</p></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");

        Console.WriteLine("PDF created successfully");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        string html = "<html><body><h1>Hello World</h1><p>This is HTML to PDF conversion.</p></body></html>";

        var pdf = renderer.RenderHtmlAsPdf(html);
        pdf.SaveAs("output.pdf");

        Console.WriteLine("PDF created successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF eliminates the using statement requirement and provides a dedicated ChromePdfRenderer class that clearly indicates its Chromium-based rendering capability. For more HTML conversion options, see the HTML to PDF documentation.

Merging Multiple PDFs

BitMiracle Docotic PDF Implementation:

// NuGet: Install-Package Docotic.Pdf
using BitMiracle.Docotic.Pdf;
using System;

class Program
{
    static void Main()
    {
        using (var pdf1 = new PdfDocument("document1.pdf"))
        using (var pdf2 = new PdfDocument("document2.pdf"))
        {
            pdf1.Append(pdf2);
            pdf1.Save("merged.pdf");
        }

        Console.WriteLine("PDFs merged successfully");
    }
}
// NuGet: Install-Package Docotic.Pdf
using BitMiracle.Docotic.Pdf;
using System;

class Program
{
    static void Main()
    {
        using (var pdf1 = new PdfDocument("document1.pdf"))
        using (var pdf2 = new PdfDocument("document2.pdf"))
        {
            pdf1.Append(pdf2);
            pdf1.Save("merged.pdf");
        }

        Console.WriteLine("PDFs merged successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF Implementation:

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

class Program
{
    static void Main()
    {
        var pdf1 = PdfDocument.FromFile("document1.pdf");
        var pdf2 = PdfDocument.FromFile("document2.pdf");

        var merged = PdfDocument.Merge(new List<PdfDocument> { pdf1, pdf2 });
        merged.SaveAs("merged.pdf");

        Console.WriteLine("PDFs merged successfully");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var pdf1 = PdfDocument.FromFile("document1.pdf");
        var pdf2 = PdfDocument.FromFile("document2.pdf");

        var merged = PdfDocument.Merge(new List<PdfDocument> { pdf1, pdf2 });
        merged.SaveAs("merged.pdf");

        Console.WriteLine("PDFs merged successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF's static Merge method accepts multiple documents directly, providing a cleaner API than the iterative Append pattern. For more options, see the PDF merging documentation.

Text Extraction

BitMiracle Docotic PDF Implementation:

// NuGet: Install-Package Docotic.Pdf
using BitMiracle.Docotic.Pdf;
using System;

class Program
{
    static void Main()
    {
        using (var pdf = new PdfDocument("document.pdf"))
        {
            string allText = "";

            foreach (var page in pdf.Pages)
            {
                allText += page.GetText();
            }

            Console.WriteLine("Extracted text:");
            Console.WriteLine(allText);
        }
    }
}
// NuGet: Install-Package Docotic.Pdf
using BitMiracle.Docotic.Pdf;
using System;

class Program
{
    static void Main()
    {
        using (var pdf = new PdfDocument("document.pdf"))
        {
            string allText = "";

            foreach (var page in pdf.Pages)
            {
                allText += page.GetText();
            }

            Console.WriteLine("Extracted text:");
            Console.WriteLine(allText);
        }
    }
}
$vbLabelText   $csharpLabel

IronPDF Implementation:

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

class Program
{
    static void Main()
    {
        var pdf = PdfDocument.FromFile("document.pdf");
        string allText = pdf.ExtractAllText();

        Console.WriteLine("Extracted text:");
        Console.WriteLine(allText);
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var pdf = PdfDocument.FromFile("document.pdf");
        string allText = pdf.ExtractAllText();

        Console.WriteLine("Extracted text:");
        Console.WriteLine(allText);
    }
}
$vbLabelText   $csharpLabel

IronPDF reduces the text extraction from a multi-line loop to a single method call. For more extraction options, see the text extraction documentation.

Password Protection and Encryption

IronPDF Implementation:

using IronPdf;

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential Document</h1>");

// Set security
pdf.SecuritySettings.UserPassword = "userPassword";
pdf.SecuritySettings.OwnerPassword = "ownerPassword";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;

pdf.SaveAs("protected.pdf");
using IronPdf;

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential Document</h1>");

// Set security
pdf.SecuritySettings.UserPassword = "userPassword";
pdf.SecuritySettings.OwnerPassword = "ownerPassword";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;

pdf.SaveAs("protected.pdf");
$vbLabelText   $csharpLabel

For comprehensive security options, see the encryption documentation.

Headers and Footers

IronPDF Implementation:

using IronPdf;

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='text-align:center; font-size:12px;'>
            Company Header - Confidential
        </div>",
    DrawDividerLine = true,
    MaxHeight = 30
};

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='text-align:center; font-size:10px;'>
            Page {page} of {total-pages}
        </div>",
    DrawDividerLine = true,
    MaxHeight = 25
};

var pdf = renderer.RenderHtmlAsPdf("<h1>Document Content</h1>");
pdf.SaveAs("with_headers.pdf");
using IronPdf;

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='text-align:center; font-size:12px;'>
            Company Header - Confidential
        </div>",
    DrawDividerLine = true,
    MaxHeight = 30
};

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = @"
        <div style='text-align:center; font-size:10px;'>
            Page {page} of {total-pages}
        </div>",
    DrawDividerLine = true,
    MaxHeight = 25
};

var pdf = renderer.RenderHtmlAsPdf("<h1>Document Content</h1>");
pdf.SaveAs("with_headers.pdf");
$vbLabelText   $csharpLabel

IronPDF supports placeholder tokens like {page} and {total-pages} for dynamic page numbering. For more options, see the headers and footers documentation.

Critical Migration Notes

Canvas to HTML Paradigm Shift

BitMiracle Docotic PDF's canvas-based drawing approach must be converted to HTML with CSS positioning:

BitMiracle Docotic PDF Pattern:

var canvas = pdfPage.Canvas;
canvas.DrawString(50, 50, "Hello, World!");
var canvas = pdfPage.Canvas;
canvas.DrawString(50, 50, "Hello, World!");
$vbLabelText   $csharpLabel

IronPDF Pattern:

var html = "<div style='position:absolute; left:50px; top:50px;'>Hello, World!</div>";
var pdf = renderer.RenderHtmlAsPdf(html);
var html = "<div style='position:absolute; left:50px; top:50px;'>Hello, World!</div>";
var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

Same Page Indexing

Both libraries use 0-based indexing (Pages[0] is the first page)—no changes needed for page access code.

Disposal Not Required

IronPDF doesn't require using statements for memory management, simplifying code structure:

// BitMiracle Docotic PDF - disposal required
using (var pdf = new PdfDocument("input.pdf"))
{
    // operations
}

// IronPDF - disposal optional
var pdf = PdfDocument.FromFile("input.pdf");
// operations - no using statement needed
// BitMiracle Docotic PDF - disposal required
using (var pdf = new PdfDocument("input.pdf"))
{
    // operations
}

// IronPDF - disposal optional
var pdf = PdfDocument.FromFile("input.pdf");
// operations - no using statement needed
$vbLabelText   $csharpLabel

Async Support

BitMiracle Docotic PDF's HtmlToPdf add-on requires async patterns everywhere. IronPDF supports both synchronous and asynchronous methods:

// Synchronous
var pdf = renderer.RenderHtmlAsPdf(html);

// Asynchronous
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
// Synchronous
var pdf = renderer.RenderHtmlAsPdf(html);

// Asynchronous
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
$vbLabelText   $csharpLabel

ASP.NET Core Integration

IronPDF Pattern:

[ApiController]
[Route("[controller]")]
public class PdfController : ControllerBase
{
    [HttpGet("generate")]
    public IActionResult GeneratePdf()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>");

        return File(pdf.BinaryData, "application/pdf", "report.pdf");
    }

    [HttpGet("generate-async")]
    public async Task<IActionResult> GeneratePdfAsync()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>");

        return File(pdf.Stream, "application/pdf", "report.pdf");
    }
}
[ApiController]
[Route("[controller]")]
public class PdfController : ControllerBase
{
    [HttpGet("generate")]
    public IActionResult GeneratePdf()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>");

        return File(pdf.BinaryData, "application/pdf", "report.pdf");
    }

    [HttpGet("generate-async")]
    public async Task<IActionResult> GeneratePdfAsync()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>");

        return File(pdf.Stream, "application/pdf", "report.pdf");
    }
}
$vbLabelText   $csharpLabel

Post-Migration Checklist

After completing the code migration, verify the following:

  • Run all unit tests to verify PDF generation works correctly
  • Compare PDF output quality (IronPDF's Chromium engine may render slightly differently—usually better)
  • Verify text extraction accuracy
  • Test form filling functionality
  • Validate digital signatures if applicable
  • Performance test batch operations
  • Test in all target environments
  • Update CI/CD pipelines
  • Remove Docotic.Pdf license files

Future-Proofing Your PDF Infrastructure

With .NET 10 on the horizon and C# 14 introducing new language features, choosing a PDF library with a unified architecture simplifies dependency management and ensures consistent feature availability. IronPDF's single-package approach means you won't need to track multiple add-on version compatibility as projects extend into 2025 and 2026.

Additional Resources


Migrating from BitMiracle Docotic PDF to IronPDF eliminates the complexity of managing multiple add-on packages while providing the same Chromium-based HTML rendering capabilities. The transition from canvas-based drawing to HTML/CSS positioning leverages web development skills most .NET developers already possess, resulting in more maintainable PDF generation code.

커티스 차우
기술 문서 작성자

커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다.

커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다.