Skip to footer content
MIGRATION GUIDES

How to Migrate from SSRS to IronPDF in C#

Migrating from SQL Server Reporting Services (SSRS) to IronPDF transforms your PDF generation workflow from a heavyweight server-based infrastructure to a lightweight, in-process library that can be embedded directly into any .NET application. This guide provides a complete, step-by-step migration path that eliminates SQL Server dependencies, report server overhead, and Microsoft ecosystem lock-in.

Why Migrate from SSRS to IronPDF

Understanding SSRS

SQL Server Reporting Services (SSRS) is Microsoft's enterprise reporting platform that requires significant infrastructure investment. SSRS is a comprehensive reporting platform from Microsoft that provides a complete suite for creating, deploying, and managing reports, offering both feature-rich and interactive report features. Developed as part of the SQL Server ecosystem, SSRS is tightly integrated with Microsoft's database solutions.

However, for many PDF generation scenarios, SSRS infrastructure is excessive. Key reasons to migrate include:

  1. Heavy Infrastructure: Requires SQL Server, Report Server, and IIS configuration
  2. Microsoft Ecosystem Lock-in: Tied to SQL Server licensing and Windows Server
  3. Complex Deployment: Report deployment, security configuration, and subscription management
  4. Expensive Licensing: SQL Server licenses, especially for enterprise features
  5. Limited Web Support: Difficult to integrate with modern SPA frameworks
  6. Maintenance Overhead: Server patching, database maintenance, report management
  7. No Cloud-Native Option: Designed for on-premises, cloud support is awkward

When SSRS is Overkill

Your NeedSSRS Overhead
Generate invoicesFull report server
Export data tablesSQL Server license
Create PDFs from dataWindows Server
Simple document generationReport subscriptions

IronPDF provides in-process PDF generation without any server infrastructure.

SSRS vs IronPDF Comparison

FeatureSSRSIronPDF
DependencyRequires SQL ServerNo specific database dependency
DeploymentServer-basedLibrary (embedded in applications)
IntegrationTight integration with MicrosoftWorks with any data source
Data VisualizationExtensive native optionsPDF-focused visualizations
ComplexityHigh (server setup required)Moderate to low (library setup)
CostSQL Server licensing costsPer developer licensing cost
HTML to PDFNoFull Chromium
URL to PDFNoYes
CSS SupportLimitedFull CSS3
JavaScriptNoFull ES2024

IronPDF, unlike SSRS, is not tied to any specific database or server ecosystem. It provides developers with a flexible library to dynamically create, edit, and manipulate PDF documents directly in C#. This decoupling from a server-based infrastructure offers a noticeable advantage—it is straightforward and adaptable, suitable for a wide array of applications beyond reporting.

For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF provides a modern Chromium rendering engine that eliminates the infrastructure complexity of SSRS.


Before You Start

Prerequisites

  1. .NET Environment: .NET Framework 4.6.2+ or .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGet Access: Ability to install NuGet packages
  3. IronPDF License: Obtain your license key from ironpdf.com

NuGet Package Changes

# SSRS has no direct NuGet - it's server-based
# Remove any ReportViewer controls

dotnet remove package Microsoft.ReportingServices.ReportViewerControl.WebForms
dotnet remove package Microsoft.ReportingServices.ReportViewerControl.WinForms

# Install IronPDF
dotnet add package IronPdf
# SSRS has no direct NuGet - it's server-based
# Remove any ReportViewer controls

dotnet remove package Microsoft.ReportingServices.ReportViewerControl.WebForms
dotnet remove package Microsoft.ReportingServices.ReportViewerControl.WinForms

# Install IronPDF
dotnet add package IronPdf
SHELL

License Configuration

// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Complete API Reference

Namespace Changes

// Before: SSRS
using Microsoft.Reporting.WebForms;
using Microsoft.Reporting.WinForms;

// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
// Before: SSRS
using Microsoft.Reporting.WebForms;
using Microsoft.Reporting.WinForms;

// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
$vbLabelText   $csharpLabel

Core API Mappings

SSRS ConceptIronPDF EquivalentNotes
LocalReportChromePdfRendererCore rendering
ServerReportRenderUrlAsPdf()URL-based rendering
.rdlc filesHTML/CSS templatesTemplate format
ReportParameterString interpolationParameters
ReportDataSourceC# data + HTMLData binding
LocalReport.Render("PDF")RenderHtmlAsPdf()PDF output
SubReportMerged PDFsNested reports
Report Server URLNot neededNo server required
ReportViewer controlNot neededDirect PDF generation
Export formatsPDF is nativeFocused output

Code Migration Examples

Example 1: HTML to PDF Conversion

Before (SSRS):

// SSRS - SQL Server Reporting Services
using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.Reporting.WebForms;
using System.IO;

class SSRSHtmlToPdf
{
    static void Main()
    {
        // Create a ReportViewer instance
        var reportViewer = new ReportViewer();
        reportViewer.ProcessingMode = ProcessingMode.Local;

        // Load RDLC report definition
        reportViewer.LocalReport.ReportPath = "Report.rdlc";

        // Add HTML content as a parameter or dataset
        var htmlContent = "<h1>Hello World</h1><p>This is HTML content.</p>";
        var param = new ReportParameter("HtmlContent", htmlContent);
        reportViewer.LocalReport.SetParameters(param);

        // Render the report to PDF
        string mimeType, encoding, fileNameExtension;
        string[] streams;
        Warning[] warnings;

        byte[] bytes = reportViewer.LocalReport.Render(
            "PDF",
            null,
            out mimeType,
            out encoding,
            out fileNameExtension,
            out streams,
            out warnings);

        File.WriteAllBytes("output.pdf", bytes);
    }
}
// SSRS - SQL Server Reporting Services
using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.Reporting.WebForms;
using System.IO;

class SSRSHtmlToPdf
{
    static void Main()
    {
        // Create a ReportViewer instance
        var reportViewer = new ReportViewer();
        reportViewer.ProcessingMode = ProcessingMode.Local;

        // Load RDLC report definition
        reportViewer.LocalReport.ReportPath = "Report.rdlc";

        // Add HTML content as a parameter or dataset
        var htmlContent = "<h1>Hello World</h1><p>This is HTML content.</p>";
        var param = new ReportParameter("HtmlContent", htmlContent);
        reportViewer.LocalReport.SetParameters(param);

        // Render the report to PDF
        string mimeType, encoding, fileNameExtension;
        string[] streams;
        Warning[] warnings;

        byte[] bytes = reportViewer.LocalReport.Render(
            "PDF",
            null,
            out mimeType,
            out encoding,
            out fileNameExtension,
            out streams,
            out warnings);

        File.WriteAllBytes("output.pdf", bytes);
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

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

class IronPdfHtmlToPdf
{
    static void Main()
    {
        // Create a ChromePdfRenderer instance
        var renderer = new ChromePdfRenderer();

        // Convert HTML string to PDF
        var htmlContent = "<h1>Hello World</h1><p>This is HTML content.</p>";
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);

        // Save the PDF file
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class IronPdfHtmlToPdf
{
    static void Main()
    {
        // Create a ChromePdfRenderer instance
        var renderer = new ChromePdfRenderer();

        // Convert HTML string to PDF
        var htmlContent = "<h1>Hello World</h1><p>This is HTML content.</p>";
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);

        // Save the PDF file
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

This example demonstrates the fundamental architectural difference. SSRS requires creating a ReportViewer instance, loading an .rdlc report definition file, setting parameters, and then calling LocalReport.Render("PDF") with multiple out parameters for metadata.

IronPDF uses a ChromePdfRenderer with RenderHtmlAsPdf() in just three lines of code. No report definition files, no parameter objects, no metadata handling required. See the HTML to PDF documentation for comprehensive examples.

Example 2: URL to PDF with Headers and Footers

Before (SSRS):

// SSRS - SQL Server Reporting Services
using System;
using System.IO;
using System.Net;
using Microsoft.Reporting.WebForms;

class SSRSUrlToPdf
{
    static void Main()
    {
        // Download HTML content from URL
        string url = "https://example.com";
        string htmlContent;

        using (var client = new WebClient())
        {
            htmlContent = client.DownloadString(url);
        }

        // Create RDLC report with header/footer configuration
        var reportViewer = new ReportViewer();
        reportViewer.ProcessingMode = ProcessingMode.Local;
        reportViewer.LocalReport.ReportPath = "WebReport.rdlc";

        // Set parameters for header and footer
        var parameters = new ReportParameter[]
        {
            new ReportParameter("HeaderText", "Company Report"),
            new ReportParameter("FooterText", "Page " + DateTime.Now.ToString()),
            new ReportParameter("HtmlContent", htmlContent)
        };
        reportViewer.LocalReport.SetParameters(parameters);

        // Render to PDF
        string mimeType, encoding, fileNameExtension;
        string[] streams;
        Warning[] warnings;

        byte[] bytes = reportViewer.LocalReport.Render(
            "PDF", null, out mimeType, out encoding,
            out fileNameExtension, out streams, out warnings);

        File.WriteAllBytes("webpage.pdf", bytes);
    }
}
// SSRS - SQL Server Reporting Services
using System;
using System.IO;
using System.Net;
using Microsoft.Reporting.WebForms;

class SSRSUrlToPdf
{
    static void Main()
    {
        // Download HTML content from URL
        string url = "https://example.com";
        string htmlContent;

        using (var client = new WebClient())
        {
            htmlContent = client.DownloadString(url);
        }

        // Create RDLC report with header/footer configuration
        var reportViewer = new ReportViewer();
        reportViewer.ProcessingMode = ProcessingMode.Local;
        reportViewer.LocalReport.ReportPath = "WebReport.rdlc";

        // Set parameters for header and footer
        var parameters = new ReportParameter[]
        {
            new ReportParameter("HeaderText", "Company Report"),
            new ReportParameter("FooterText", "Page " + DateTime.Now.ToString()),
            new ReportParameter("HtmlContent", htmlContent)
        };
        reportViewer.LocalReport.SetParameters(parameters);

        // Render to PDF
        string mimeType, encoding, fileNameExtension;
        string[] streams;
        Warning[] warnings;

        byte[] bytes = reportViewer.LocalReport.Render(
            "PDF", null, out mimeType, out encoding,
            out fileNameExtension, out streams, out warnings);

        File.WriteAllBytes("webpage.pdf", bytes);
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

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

class IronPdfUrlToPdf
{
    static void Main()
    {
        // Create a ChromePdfRenderer instance
        var renderer = new ChromePdfRenderer();

        // Configure rendering options with header and footer
        renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
        {
            HtmlFragment = "<div style='text-align:center'>Company Report</div>"
        };

        renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
        {
            HtmlFragment = "<div style='text-align:center'>Page {page} of {total-pages} - " + DateTime.Now.ToString("MM/dd/yyyy") + "</div>"
        };

        // Convert URL to PDF
        string url = "https://example.com";
        var pdf = renderer.RenderUrlAsPdf(url);

        // Save the PDF file
        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class IronPdfUrlToPdf
{
    static void Main()
    {
        // Create a ChromePdfRenderer instance
        var renderer = new ChromePdfRenderer();

        // Configure rendering options with header and footer
        renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
        {
            HtmlFragment = "<div style='text-align:center'>Company Report</div>"
        };

        renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter()
        {
            HtmlFragment = "<div style='text-align:center'>Page {page} of {total-pages} - " + DateTime.Now.ToString("MM/dd/yyyy") + "</div>"
        };

        // Convert URL to PDF
        string url = "https://example.com";
        var pdf = renderer.RenderUrlAsPdf(url);

        // Save the PDF file
        pdf.SaveAs("webpage.pdf");
    }
}
$vbLabelText   $csharpLabel

SSRS cannot directly convert URLs to PDF. You must manually download HTML content with WebClient.DownloadString(), create a separate .rdlc report file, pass the HTML and header/footer text as ReportParameter arrays, then render with the complex Render() method signature.

IronPDF's RenderUrlAsPdf() handles the entire process in a single call. Headers and footers are configured with HtmlHeaderFooter objects that support full HTML/CSS and placeholders like {page} and {total-pages}. Learn more in our tutorials.

Example 3: Database-Driven Report

Before (SSRS):

// SSRS - SQL Server Reporting Services
using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.Reporting.WebForms;
using System.IO;

class SSRSDatabaseReport
{
    static void Main()
    {
        // Create a ReportViewer instance
        var reportViewer = new ReportViewer();
        reportViewer.ProcessingMode = ProcessingMode.Local;
        reportViewer.LocalReport.ReportPath = "SalesReport.rdlc";

        // Create database connection and fetch data
        string connString = "Server=localhost;Database=SalesDB;Integrated Security=true;";
        using (var connection = new SqlConnection(connString))
        {
            var adapter = new SqlDataAdapter("SELECT * FROM Sales", connection);
            var dataSet = new DataSet();
            adapter.Fill(dataSet, "Sales");

            // Bind data to report
            var dataSource = new ReportDataSource("SalesDataSet", dataSet.Tables[0]);
            reportViewer.LocalReport.DataSources.Clear();
            reportViewer.LocalReport.DataSources.Add(dataSource);
        }

        // Render to PDF
        string mimeType, encoding, fileNameExtension;
        string[] streams;
        Warning[] warnings;

        byte[] bytes = reportViewer.LocalReport.Render(
            "PDF", null, out mimeType, out encoding,
            out fileNameExtension, out streams, out warnings);

        File.WriteAllBytes("sales-report.pdf", bytes);
    }
}
// SSRS - SQL Server Reporting Services
using System;
using System.Data;
using System.Data.SqlClient;
using Microsoft.Reporting.WebForms;
using System.IO;

class SSRSDatabaseReport
{
    static void Main()
    {
        // Create a ReportViewer instance
        var reportViewer = new ReportViewer();
        reportViewer.ProcessingMode = ProcessingMode.Local;
        reportViewer.LocalReport.ReportPath = "SalesReport.rdlc";

        // Create database connection and fetch data
        string connString = "Server=localhost;Database=SalesDB;Integrated Security=true;";
        using (var connection = new SqlConnection(connString))
        {
            var adapter = new SqlDataAdapter("SELECT * FROM Sales", connection);
            var dataSet = new DataSet();
            adapter.Fill(dataSet, "Sales");

            // Bind data to report
            var dataSource = new ReportDataSource("SalesDataSet", dataSet.Tables[0]);
            reportViewer.LocalReport.DataSources.Clear();
            reportViewer.LocalReport.DataSources.Add(dataSource);
        }

        // Render to PDF
        string mimeType, encoding, fileNameExtension;
        string[] streams;
        Warning[] warnings;

        byte[] bytes = reportViewer.LocalReport.Render(
            "PDF", null, out mimeType, out encoding,
            out fileNameExtension, out streams, out warnings);

        File.WriteAllBytes("sales-report.pdf", bytes);
    }
}
$vbLabelText   $csharpLabel

After (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Data;
using System.Data.SqlClient;
using System.Text;

class IronPdfDatabaseReport
{
    static void Main()
    {
        // Create database connection and fetch data
        string connString = "Server=localhost;Database=SalesDB;Integrated Security=true;";
        var dataTable = new DataTable();

        using (var connection = new SqlConnection(connString))
        {
            var adapter = new SqlDataAdapter("SELECT * FROM Sales", connection);
            adapter.Fill(dataTable);
        }

        // Build HTML table from data
        var htmlBuilder = new StringBuilder();
        htmlBuilder.Append("<h1>Sales Report</h1><table border='1'><tr>");

        foreach (DataColumn column in dataTable.Columns)
            htmlBuilder.Append($"<th>{column.ColumnName}</th>");
        htmlBuilder.Append("</tr>");

        foreach (DataRow row in dataTable.Rows)
        {
            htmlBuilder.Append("<tr>");
            foreach (var item in row.ItemArray)
                htmlBuilder.Append($"<td>{item}</td>");
            htmlBuilder.Append("</tr>");
        }
        htmlBuilder.Append("</table>");

        // Convert to PDF
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlBuilder.ToString());
        pdf.SaveAs("sales-report.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Data;
using System.Data.SqlClient;
using System.Text;

class IronPdfDatabaseReport
{
    static void Main()
    {
        // Create database connection and fetch data
        string connString = "Server=localhost;Database=SalesDB;Integrated Security=true;";
        var dataTable = new DataTable();

        using (var connection = new SqlConnection(connString))
        {
            var adapter = new SqlDataAdapter("SELECT * FROM Sales", connection);
            adapter.Fill(dataTable);
        }

        // Build HTML table from data
        var htmlBuilder = new StringBuilder();
        htmlBuilder.Append("<h1>Sales Report</h1><table border='1'><tr>");

        foreach (DataColumn column in dataTable.Columns)
            htmlBuilder.Append($"<th>{column.ColumnName}</th>");
        htmlBuilder.Append("</tr>");

        foreach (DataRow row in dataTable.Rows)
        {
            htmlBuilder.Append("<tr>");
            foreach (var item in row.ItemArray)
                htmlBuilder.Append($"<td>{item}</td>");
            htmlBuilder.Append("</tr>");
        }
        htmlBuilder.Append("</table>");

        // Convert to PDF
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlBuilder.ToString());
        pdf.SaveAs("sales-report.pdf");
    }
}
$vbLabelText   $csharpLabel

SSRS requires a pre-designed .rdlc report file ("SalesReport.rdlc"), filling a DataSet, creating a ReportDataSource with a specific name ("SalesDataSet") that must match the report definition, clearing existing data sources, adding the new data source, then rendering.

IronPDF uses your existing data access code (same SqlDataAdapter pattern), then builds HTML dynamically with StringBuilder. You have full control over the layout using standard HTML/CSS—no proprietary report definition files required.


Feature Comparison

FeatureSSRSIronPDF
Infrastructure
Server RequiredYes (Report Server)No
SQL Server LicenseRequiredNot needed
Windows ServerRequiredAny platform
Database RequiredYes (ReportServer DB)No
Development
Visual DesignerYes (.rdlc)HTML editors
Template FormatRDLC/RDLHTML/CSS/Razor
Data SourcesBuilt-in DSNAny C# data
Rendering
HTML to PDFNoFull Chromium
URL to PDFNoYes
CSS SupportLimitedFull CSS3
JavaScriptNoFull ES2024
ChartsBuilt-inVia JS libraries
Deployment
Report DeploymentTo serverWith app
ConfigurationComplexSimple
MaintenanceHighLow

Common Migration Issues

Issue 1: RDLC Report Definitions

SSRS: Uses proprietary .rdlc XML format.

Solution: Convert to HTML templates:

  1. Open .rdlc in Visual Studio
  2. Document the layout structure
  3. Recreate in HTML/CSS
  4. Use Razor for data binding

Issue 2: Shared Data Sources

SSRS: Connection strings in Report Server.

Solution: Use your application's data access layer:

var data = await _dbContext.Sales.ToListAsync();
// Then bind to HTML template
var data = await _dbContext.Sales.ToListAsync();
// Then bind to HTML template
$vbLabelText   $csharpLabel

Issue 3: Report Parameters UI

SSRS: Built-in parameter prompts.

Solution: Build parameter UI in your application:

// Your own parameter form, then:
var pdf = GenerateReport(startDate, endDate, region);
// Your own parameter form, then:
var pdf = GenerateReport(startDate, endDate, region);
$vbLabelText   $csharpLabel

Issue 4: Subscriptions/Scheduled Reports

SSRS: Built-in subscription engine.

Solution: Use background job framework:

// Using Hangfire or similar
RecurringJob.AddOrUpdate("weekly-report",
    () => GenerateAndEmailReport(), Cron.Weekly);
// Using Hangfire or similar
RecurringJob.AddOrUpdate("weekly-report",
    () => GenerateAndEmailReport(), Cron.Weekly);
$vbLabelText   $csharpLabel

Migration Checklist

Pre-Migration

  • Inventory all SSRS reports (.rdlc files)
  • Document data sources and connections
  • Screenshot report layouts for visual reference
  • List report parameters for each report
  • Note subscription schedules
  • Obtain IronPDF license key from ironpdf.com

Code Updates

  • Remove ReportViewer packages
  • Install IronPdf NuGet package
  • Convert .rdlc files to HTML templates
  • Replace LocalReport with ChromePdfRenderer
  • Replace ReportDataSource with C# data + HTML templates
  • Replace ReportParameter with string interpolation
  • Replace LocalReport.Render("PDF") with RenderHtmlAsPdf()
  • Implement headers/footers with HtmlHeaderFooter
  • Add license initialization at application startup

Infrastructure

  • Plan Report Server decommission
  • Migrate subscriptions to job scheduler (Hangfire, etc.)
  • Update deployment scripts

Testing

  • Compare PDF output visually
  • Verify data accuracy
  • Test pagination
  • Check all parameters
  • Performance testing

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More