DEV Community

IronSoftware
IronSoftware

Posted on

How to Convert PDF to MemoryStream in C# (.NET Guide)

Need to serve a PDF from an API without saving it to disk? Work with PDF bytes in memory for database storage? Here's how to convert PDFs to MemoryStream and byte arrays in C#.

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

var renderer = new [ChromePdfRenderer](https://ironpdf.com/blog/videos/how-to-render-an-html-file-to-pdf-in-csharp-ironpdf/)();
var pdf = renderer.RenderHtmlAsPdf("<h1>Invoice #1234</h1>");

// Get as MemoryStream
Stream pdfStream = pdf.Stream;

// Or get as byte array
byte[] pdfBytes = pdf.BinaryData;
Enter fullscreen mode Exit fullscreen mode

Two properties. No file I/O. Your PDF lives entirely in memory.

Why Would I Need a PDF in Memory?

Plenty of real-world scenarios require PDFs without touching the filesystem:

Web APIs - Return a PDF from a controller action without creating temp files
Database storage - Store PDF binary data in SQL Server's varbinary column
Email attachments - Attach PDFs to emails using System.Net.Mail
Cloud functions - Azure Functions and AWS Lambda have read-only filesystems
Microservices - Pass PDFs between services via message queues

In all these cases, writing to disk and reading back wastes time and creates cleanup headaches.

How Do I Get a PDF as a MemoryStream?

IronPDF exposes the rendered PDF through its Stream property:

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

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(@"
    <html>
    <body>
        <h1>Quarterly Report</h1>
        <p>Q4 2024 Results</p>
    </body>
    </html>");

Stream memoryStream = pdf.Stream;

// The stream is positioned at the beginning
// Ready for immediate use
Enter fullscreen mode Exit fullscreen mode

The Stream property returns a System.IO.Stream that you can pass directly to any method expecting a stream—no casting or conversion needed.

How Do I Get a PDF as a Byte Array?

For scenarios where you need raw bytes (database storage, Base64 encoding), use BinaryData:

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

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

byte[] pdfBytes = pdf.BinaryData;

// Store in database
await connection.ExecuteAsync(
    "INSERT INTO Documents (Content) VALUES (@Content)",
    new { Content = pdfBytes });
Enter fullscreen mode Exit fullscreen mode

BinaryData gives you the complete PDF file as a byte[]. This is the same data you'd get from File.ReadAllBytes() on a saved PDF—just without the file.

How Do I Return a PDF from an ASP.NET Core API?

The most common use case. Here's a controller that generates and returns a PDF without any disk access:

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

[ApiController]
[Route("api/[controller]")]
public class InvoiceController : ControllerBase
{
    [HttpGet("{id}")]
    public IActionResult GetInvoice(int id)
    {
        var invoice = GetInvoiceData(id);

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(BuildInvoiceHtml(invoice));

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

The File() method accepts a byte array. The third parameter sets the download filename. Your users get a properly-named PDF download with zero temp files created.

How Do I Load an Existing PDF into Memory?

Sometimes you need to read an existing PDF file into memory for processing:

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

// From a file path
var pdf = PdfDocument.FromFile("existing.pdf");
byte[] bytes = pdf.BinaryData;
Stream stream = pdf.Stream;

// From a URL
var pdfFromUrl = PdfDocument.FromUrl("https://example.com/document.pdf");
byte[] urlBytes = pdfFromUrl.BinaryData;
Enter fullscreen mode Exit fullscreen mode

This is useful when you need to merge, watermark, or otherwise modify an existing PDF before serving it.

How Do I Convert a MemoryStream Back to a PDF?

Going the other direction—from bytes or stream back to a PdfDocument:

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

// From byte array
byte[] pdfBytes = GetBytesFromDatabase();
var pdf = new PdfDocument(pdfBytes);

// From stream
Stream pdfStream = GetStreamFromSomewhere();
var pdfFromStream = new PdfDocument(pdfStream);

// Now you can manipulate it
pdf.ApplyWatermark("<h2>CONFIDENTIAL</h2>");
byte[] watermarkedBytes = pdf.BinaryData;
Enter fullscreen mode Exit fullscreen mode

The PdfDocument constructor accepts both byte[] and Stream. Once loaded, you have full access to all manipulation methods.

What About Memory Management?

PDFs can be large. A 100-page document might consume 50MB or more. Keep these practices in mind:

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

// Good: Dispose when done
using (var pdf = renderer.RenderHtmlAsPdf(html))
{
    var bytes = pdf.BinaryData;
    // Use bytes...
} // PDF resources freed here

// Better for large files: Stream directly
[HttpGet("{id}")]
public IActionResult GetLargeReport(int id)
{
    var pdf = GenerateLargeReport(id);

    // Stream property avoids copying the entire PDF into a new byte[]
    return File(pdf.Stream, "application/pdf", "report.pdf");
}
Enter fullscreen mode Exit fullscreen mode

Using pdf.Stream is slightly more memory-efficient than pdf.BinaryData because it avoids an extra array allocation. For small PDFs, the difference is negligible. For multi-megabyte documents, it adds up.

How Do I Send a PDF as an Email Attachment?

A common workflow—generate a PDF and email it:

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

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(invoiceHtml);

var message = new MailMessage("from@company.com", "customer@example.com")
{
    Subject = "Your Invoice",
    Body = "Please find your invoice attached."
};

// Create attachment from memory stream
var attachment = new Attachment(
    new MemoryStream(pdf.BinaryData),
    "invoice.pdf",
    "application/pdf");

message.Attachments.Add(attachment);

using var smtp = new SmtpClient("smtp.company.com");
await smtp.SendMailAsync(message);
Enter fullscreen mode Exit fullscreen mode

The Attachment constructor accepts a Stream. Wrap your BinaryData in a MemoryStream and you're done.

How Do I Store PDFs in Azure Blob Storage?

Cloud storage APIs work with streams and bytes:

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

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(reportHtml);

var blobClient = containerClient.GetBlobClient($"reports/{reportId}.pdf");

// Upload directly from stream
await blobClient.UploadAsync(
    new MemoryStream(pdf.BinaryData),
    overwrite: true);
Enter fullscreen mode Exit fullscreen mode

No temp files. The PDF goes from render to cloud in one step.

Quick Reference: Stream vs BinaryData

Property Returns Best For
Stream System.IO.Stream Streaming responses, minimal memory
BinaryData byte[] Database storage, email attachments, Base64

Both properties access the same underlying PDF data. Choose based on what the consuming API expects.

The key insight: modern PDF libraries shouldn't require filesystem access. When you generate a PDF, you should have immediate access to its bytes. Everything else—saving, streaming, storing—is just routing those bytes to the right destination.

For more details on working with PDFs in memory, see the full IronPDF MemoryStream 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)