DEV Community

IronSoftware
IronSoftware

Posted on

Razor View to PDF in C# (.NET Tutorial)

Razor views give you HTML templating with C# logic. Convert those CSHTML files directly to PDF—use your existing views for reports, invoices, and documents without duplicating template code.

using IronPdf;
using IronPdf.Extensions.Razor;
// Install via NuGet: Install-Package IronPdf
// Install via NuGet: Install-Package IronPdf.Extensions.Razor

var renderer = new [ChromePdfRenderer](https://ironpdf.com/blog/videos/how-to-render-webgl-sites-to-pdf-in-csharp-ironpdf/)();
var pdf = renderer.RenderRazorToPdf("/Views/Invoice.cshtml", model);
pdf.SaveAs("invoice.pdf");
Enter fullscreen mode Exit fullscreen mode

IronPDF's Razor extension renders CSHTML files with full model binding and layout support.

Why Use Razor Views for PDFs?

Razor views offer several advantages:

  • Reuse existing templates: Your web views become PDF templates
  • Familiar syntax: If you know Razor, you know how to create PDFs
  • Strong typing: Model binding catches errors at compile time
  • Layout support: Master pages work in PDFs too
  • Partial views: Compose complex documents from components

How Do I Set Up Razor to PDF?

Install both packages:

// Package Manager Console
Install-Package IronPdf
Install-Package IronPdf.Extensions.Razor
Enter fullscreen mode Exit fullscreen mode

Or via .NET CLI:

dotnet add package IronPdf
dotnet add package IronPdf.Extensions.Razor
Enter fullscreen mode Exit fullscreen mode

How Do I Create a Basic Invoice PDF?

Start with a Razor view and model:

// Models/InvoiceModel.cs
public class InvoiceModel
{
    public string InvoiceNumber { get; set; }
    public DateTime Date { get; set; }
    public string CustomerName { get; set; }
    public List<LineItem> Items { get; set; }
    public decimal Total => Items.Sum(x => x.Quantity * x.UnitPrice);
}

public class LineItem
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Create the Razor view:

@* Views/Invoice.cshtml *@
@model InvoiceModel

<!DOCTYPE html>
<html>
<head>
    <style>
        body { font-family: Arial, sans-serif; padding: 40px; }
        table { width: 100%; border-collapse: collapse; }
        th, td { border: 1px solid #ddd; padding: 10px; text-align: left; }
        .total { font-weight: bold; font-size: 1.2em; }
    </style>
</head>
<body>
    <h1>Invoice @Model.InvoiceNumber</h1>
    <p>Date: @Model.Date.ToShortDateString()</p>
    <p>Customer: @Model.CustomerName</p>

    <table>
        <thead>
            <tr>
                <th>Description</th>
                <th>Qty</th>
                <th>Unit Price</th>
                <th>Total</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Items)
            {
                <tr>
                    <td>@item.Description</td>
                    <td>@item.Quantity</td>
                    <td>@item.UnitPrice.ToString("C")</td>
                    <td>@((item.Quantity * item.UnitPrice).ToString("C"))</td>
                </tr>
            }
        </tbody>
    </table>

    <p class="total">Total: @Model.Total.ToString("C")</p>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Render to PDF:

using IronPdf;
using IronPdf.Extensions.Razor;
// Install via NuGet: Install-Package IronPdf
// Install via NuGet: Install-Package IronPdf.Extensions.Razor

var model = new InvoiceModel
{
    InvoiceNumber = "INV-2024-001",
    Date = DateTime.Now,
    CustomerName = "Acme Corp",
    Items = new List<LineItem>
    {
        new() { Description = "Widget A", Quantity = 5, UnitPrice = 29.99m },
        new() { Description = "Widget B", Quantity = 3, UnitPrice = 49.99m }
    }
};

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderRazorToPdf("/Views/Invoice.cshtml", model);
pdf.SaveAs("invoice.pdf");
Enter fullscreen mode Exit fullscreen mode

How Do I Use Layouts in PDF Views?

Razor layouts work for PDFs:

@* Views/Shared/_PdfLayout.cshtml *@
<!DOCTYPE html>
<html>
<head>
    <style>
        body { font-family: 'Segoe UI', sans-serif; margin: 0; padding: 40px; }
        header { border-bottom: 2px solid #333; padding-bottom: 20px; margin-bottom: 30px; }
        footer { position: fixed; bottom: 20px; left: 40px; right: 40px; text-align: center; font-size: 12px; color: #666; }
    </style>
    @RenderSection("Styles", required: false)
</head>
<body>
    <header>
        <img src="logo.png" alt="Company Logo" style="height: 50px;" />
    </header>

    @RenderBody()

    <footer>
        &copy; @DateTime.Now.Year Your Company | Confidential
    </footer>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Use the layout in your view:

@* Views/Report.cshtml *@
@model ReportModel
@{
    Layout = "_PdfLayout";
}

@section Styles {
    <style>
        .chart { width: 100%; margin: 20px 0; }
    </style>
}

<h1>@Model.Title</h1>
<p>Generated: @DateTime.Now</p>

<div class="chart">
    <!-- Report content -->
</div>
Enter fullscreen mode Exit fullscreen mode

How Do I Include Partial Views?

Break complex PDFs into components:

@* Views/Shared/_CustomerDetails.cshtml *@
@model Customer

<div class="customer-info">
    <h3>@Model.Name</h3>
    <p>@Model.Address</p>
    <p>@Model.Email</p>
</div>
Enter fullscreen mode Exit fullscreen mode

Use partials in your main view:

@* Views/Order.cshtml *@
@model OrderModel

<h1>Order Confirmation</h1>

<partial name="_CustomerDetails" model="Model.Customer" />

<h2>Order Items</h2>
@foreach (var item in Model.Items)
{
    <partial name="_OrderItem" model="item" />
}
Enter fullscreen mode Exit fullscreen mode

How Do I Pass ViewData and ViewBag?

Access ViewBag and ViewData in PDF views:

using IronPdf;
using IronPdf.Extensions.Razor;
// Install via NuGet: Install-Package IronPdf
// Install via NuGet: Install-Package IronPdf.Extensions.Razor

var renderer = new ChromePdfRenderer();

var viewData = new Dictionary<string, object>
{
    { "CompanyName", "Acme Corp" },
    { "ReportDate", DateTime.Now }
};

var pdf = renderer.RenderRazorToPdf("/Views/Report.cshtml", model, viewData);
Enter fullscreen mode Exit fullscreen mode

In the view:

@{
    var companyName = ViewData["CompanyName"];
    var reportDate = ViewData["ReportDate"];
}

<h1>@companyName Report</h1>
<p>Generated: @reportDate</p>
Enter fullscreen mode Exit fullscreen mode

How Do I Handle Conditional Content?

Use Razor's full C# syntax:

@model OrderModel

@if (Model.IsPaid)
{
    <div class="paid-stamp">PAID</div>
}
else
{
    <div class="due-stamp">PAYMENT DUE: @Model.DueDate.ToShortDateString()</div>
}

@switch (Model.Status)
{
    case OrderStatus.Pending:
        <span class="badge pending">Pending</span>
        break;
    case OrderStatus.Shipped:
        <span class="badge shipped">Shipped</span>
        break;
    case OrderStatus.Delivered:
        <span class="badge delivered">Delivered</span>
        break;
}
Enter fullscreen mode Exit fullscreen mode

How Do I Format Data in Views?

Use tag helpers and HTML helpers:

@model FinancialReport

<table>
    @foreach (var row in Model.Data)
    {
        <tr>
            <td>@row.Date.ToString("MMM yyyy")</td>
            <td>@row.Revenue.ToString("C")</td>
            <td class="@(row.Growth >= 0 ? "positive" : "negative")">
                @row.Growth.ToString("P1")
            </td>
        </tr>
    }
</table>
Enter fullscreen mode Exit fullscreen mode

How Do I Generate PDFs from Controllers?

Return PDFs directly from ASP.NET Core controllers:

using IronPdf;
using IronPdf.Extensions.Razor;
// Install via NuGet: Install-Package IronPdf
// Install via NuGet: Install-Package IronPdf.Extensions.Razor

public class InvoiceController : Controller
{
    public IActionResult Download(int id)
    {
        var invoice = _invoiceService.GetById(id);

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderRazorToPdf("/Views/Invoice.cshtml", invoice);

        return File(pdf.BinaryData, "application/pdf", $"invoice-{id}.pdf");
    }
}
Enter fullscreen mode Exit fullscreen mode

How Do I Add Page Numbers?

Use headers and footers:

using IronPdf;
using IronPdf.Extensions.Razor;
// Install via NuGet: Install-Package IronPdf
// Install via NuGet: Install-Package IronPdf.Extensions.Razor

var renderer = new ChromePdfRenderer();

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

var pdf = renderer.RenderRazorToPdf("/Views/Report.cshtml", model);
Enter fullscreen mode Exit fullscreen mode

How Do I Handle Images in Razor PDFs?

Use absolute paths or Base64:

@* Absolute URL *@
<img src="https://example.com/logo.png" />

@* Base64 embedded *@
<img src="data:image/png;base64,@Model.LogoBase64" />

@* Local file with base path *@
<img src="file:///C:/app/wwwroot/images/logo.png" />
Enter fullscreen mode Exit fullscreen mode

Or set the base URL:

using IronPdf;
using IronPdf.Extensions.Razor;
// Install via NuGet: Install-Package IronPdf
// Install via NuGet: Install-Package IronPdf.Extensions.Razor

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.BaseUrl = new Uri("https://myapp.com/");

var pdf = renderer.RenderRazorToPdf("/Views/Report.cshtml", model);
Enter fullscreen mode Exit fullscreen mode

Quick Reference

Method Description
RenderRazorToPdf() Render CSHTML to PDF
RenderRazorToPdfAsync() Async rendering
RenderHtmlAsPdf() Fallback for HTML strings
View Feature PDF Support
Layouts Full support
Partial views Full support
Sections Full support
ViewData/ViewBag Full support
Tag helpers Full support
Model binding Full support

Razor views let you build PDF templates with the same tools you use for web pages—no separate templating language required.

For more Razor to PDF options, see the IronPDF Razor Pages documentation.


Written by Jacob Mellor, CTO at Iron Software. Jacob created IronPDF and leads a team of 50+ engineers building .NET document processing libraries.

Top comments (0)