Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
To show a PDF in an ASP.NET page, serve it at a URL and put that URL in an HTML <iframe> or <embed>. In ASP.NET Core, a public, static PDF can live under wwwroot; a generated or protected PDF should instead come from an endpoint that returns application/pdf and performs any required authorization. The browser’s PDF viewer renders the embedded document, so provide a direct link as a fallback and test the browsers your users rely on.
Choose the right way to serve the PDF
The important choice is not whether to use an iframe or an embed tag; it is where the PDF lives and who is allowed to retrieve it. A static public document can be delivered like another web asset. A generated report or private document should be returned by application code. Blazor can also stream a file to an iframe when a public PDF URL is unsuitable.
| PDF and access situation | Recommended approach | What the browser receives |
|---|---|---|
| Public, static file | Put it in wwwroot, enable static-file delivery, and use its URL in an iframe or embed. |
A separate request for the PDF asset. |
| Generated on demand | Return the generated bytes or stream from a route using a file result. | A response with the PDF media type, normally application/pdf. |
| Private or permission-dependent file | Return it from an authorized endpoint that checks the current user’s access. | The PDF only after the application permits the request. |
| Blazor content with no suitable public URL | Stream the PDF to JavaScript interop and set the iframe source to a Blob object URL. | A browser-local object URL for the streamed PDF. |
These examples use ASP.NET Core patterns. For current static-asset setup, follow the documentation for the target .NET version: current .NET 10 guidance describes MapStaticAssets, while UseStaticFiles is also documented. Exact setup depends on the app template and version; files under the web root are addressed by a path relative to that root.
Embed a public static PDF in ASP.NET Core
1. Put the file under the web root
For example, place guide.pdf at wwwroot/files/guide.pdf. With static assets configured, its typical path is /files/guide.pdf. If the application is mounted under a path base or has custom routing, use the actual public URL rather than assuming the root-relative example applies.
#1 Best Overall
2. Add the iframe to a Razor view or page
<iframe src="/files/guide.pdf"
title="PDF: Guide"
width="100%"
height="700">
<a href="/files/guide.pdf">Open the PDF</a>
</iframe>
The title gives the embedded browsing context a meaningful name. Set the height to suit your layout; the example is only a starting point. The fallback link lets a visitor open the document directly if the embedded viewer is unavailable or inconvenient. An <embed> element can also reference the same URL, but the iframe pattern makes it straightforward to include fallback content.
The page does not contain the PDF’s binary data. The browser makes a separate request to the URL in src, and the browser’s PDF viewer handles display.
3. Confirm static-file delivery
Enable static assets using the approach documented for your application’s .NET version and ensure the file is included in the deployed web root. ASP.NET Core serves recognized extensions with a content type; if your deployment uses custom file mappings, configure them deliberately. Check the response for the PDF URL in the browser’s network tools: it should resolve to the intended file and be served as a PDF, not as an error page or an unrelated HTML response.
Rank #2
Return a generated or protected PDF from an endpoint
Do not put confidential documents in a publicly addressable static folder and expect an iframe to protect them. Instead, make the iframe’s source an application route that checks access and returns the document. Microsoft’s Minimal API documentation shows TypedResults.File(pdf, "application/pdf", "report.pdf"); controller actions can use ControllerBase.File() with a byte array or stream.
Minimal API example
This illustrates the response shape when the PDF bytes have already been generated. Replace the example data source with your own report generation or storage code, and add the appropriate authorization and ownership checks for private documents.
app.MapGet("/reports/{id}/pdf", (string id) =>
{
byte[] pdf = GetReportPdf(id); // Generate or retrieve the PDF.
return TypedResults.File(pdf, "application/pdf", "report.pdf");
});
GetReportPdf is application-specific and is not a built-in ASP.NET method. In a real endpoint, validate the identifier and verify that the requester may access that report before retrieving or returning its bytes. Then point the iframe at the endpoint, for example /reports/123/pdf, rather than at a static file path.
Controller-based alternative
In a controller, use the corresponding file result for the byte array or stream your application has obtained:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
public IActionResult ReportPdf(string id)
{
// Validate id and authorize access before retrieving the document.
byte[] pdf = GetReportPdf(id);
return File(pdf, "application/pdf", "report.pdf");
}
The retrieval helper and authorization logic must come from your application. The response filename or disposition can affect whether a browser downloads or displays a file. The cited Microsoft file-result examples establish how to return a file and specify its media type, but do not fully define inline behavior across browsers. If inline display is a requirement, inspect the response headers and test the target browser environments rather than assuming a filename alone controls the viewer.
Stream a PDF to an iframe in Blazor
Microsoft’s Blazor guidance demonstrates retrieving a PDF stream, wrapping it in a DotNetStreamReference, passing it through JavaScript interop, and assigning a Blob object URL to the iframe. The JavaScript creates a PDF Blob, sets the iframe title, and revokes the object URL after load so it is not retained unnecessarily. This is useful when the app should not expose a public PDF URL. If a suitable PDF URL is already available, the simpler documented option is to use it directly as the iframe source.
Rank #4
Keep the example’s trust boundary in mind. Microsoft warns that an improperly implemented iframe can create security vulnerabilities when it loads untrusted content or user input. Do not let arbitrary user-provided URLs become iframe sources without controls appropriate to your application.
Browser display, fallback, and viewer control
An iframe creates an embedded browsing context; it is not itself a PDF renderer. Whether the document appears inline depends on the browser and its PDF-viewing behavior. A Microsoft Q&A answer discusses native browser PDF support as a factor and mentions PDF.js for applications that need more controlled rendering. Treat that community answer as guidance, not a compatibility guarantee.
- Offer a normal “Open PDF” or download link alongside the embedded view.
- Test the actual desktop and mobile browsers in scope, including the way your endpoint responds.
- If consistent custom controls, page rendering, or annotation behavior is central to the application, evaluate a maintained viewer library such as PDF.js. Verify its current documentation, compatibility, and licensing separately.
No browser-by-browser support matrix is established here, so avoid promising identical controls or inline behavior everywhere.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Protect documents and iframe inputs
- Enforce authorization on the PDF request. Hiding a link or putting a URL in an iframe is not access control. A private endpoint must validate permissions each time the file is requested.
- Keep protected files out of public static locations. Files placed under the web root are directly addressable under the configured static-file setup.
- Treat user-supplied PDF URLs and iframe sources as untrusted. Restrict permitted sources and validate access before returning sensitive content.
- Encode output and validate input. Avoid concatenating untrusted values into HTML or JavaScript. Microsoft ASP.NET Core security guidance warns that HTML or script injection can execute in a user’s browser.
- Use the correct media type. Dynamic file responses should identify PDFs as
application/pdf; configure static extension mappings deliberately if the default recognition is not suitable.
Legacy ASP.NET Web Forms
In Web Forms, the same browser-level idea applies: serve the PDF at a separate URL and reference it from the page. For a document stored in a database, the older Microsoft Web Forms tutorial describes returning binary data from an ASP.NET page by setting Response.ContentType and writing bytes. Adapt that pattern to the actual Web Forms version and storage model; do not copy unrelated bitmap-processing details from a tutorial into PDF handling. If the document is private, enforce access checks before writing the response.
Troubleshoot common embedding problems
| Symptom | Likely cause | What to check or change |
|---|---|---|
| The frame shows an error or a blank page. | The URL is wrong, the file is missing from deployment, static delivery is not enabled, or the endpoint returned an error. | Open the PDF URL directly and inspect its response in browser network tools. Verify the deployed path, app path base, route, and status. |
| The PDF downloads instead of appearing inline. | The response disposition or browser behavior favors download. | Inspect response headers and test the target browser. The file-result examples alone do not guarantee uniform inline display. |
| The browser displays HTML or garbled content instead of a PDF. | The endpoint may return an error page, a login redirect, or an incorrect media type. | Check the actual response body, status, authentication flow, and Content-Type; use application/pdf for a PDF response. |
| Public users can access a file meant to be private. | The document was placed in a public static directory or the PDF route omitted authorization. | Move it outside the public web root and serve it through a route that checks access before returning bytes. |
| A Blazor iframe stops working after streaming. | The JavaScript interop or Blob URL lifecycle may be incomplete. | Follow the documented stream-reference pattern, set the Blob’s PDF type, ensure the iframe source is assigned, and revoke the object URL after load. |
| Untrusted content appears in the frame. | A user-controlled URL or value was accepted without appropriate validation. | Restrict acceptable sources, validate access, and avoid inserting untrusted data into HTML or JavaScript. |
Or skip the browser setup
ScreenshotNeo is a separate way to capture a web page as an image or PDF; it does not embed or serve an existing PDF from your ASP.NET application. Its API can be useful if your goal is to capture a rendered page as a PDF instead. See the ScreenshotNeo documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Before capture, it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents and MCP clients. The free plan includes 1,000 screenshots a month without a card; paid plans start at $5 for 3,000.
Sign up for 1,000 free screenshots a month with no card.
Frequently Asked Questions
Can I embed a PDF with an object or embed tag instead of an iframe?
Yes. Those HTML elements can also reference a PDF URL, but the browser still determines how the PDF is displayed.
Does an iframe make a PDF private?
No. Privacy depends on the server checking authorization when it receives the PDF request.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

