Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Short answer: iTextSharp cannot execute a .cshtml Razor template. If the file contains Razor code, render it through the ASP.NET/Razor view engine with its model and request/view context, capture the resulting HTML, and then pass that HTML to iTextSharp XMLWorker. If the file is already ordinary HTML, read it as text or a stream and parse it directly.
Razor is server code embedded in markup; expressions are evaluated by ASP.NET while the view renders. iTextSharp/XMLWorker is an HTML-to-PDF parser, not an ASP.NET host, MVC view engine, Razor runtime, or browser.
First determine what the .cshtml file contains
Razor template
A view containing @Model.Name, @if, @foreach, directives such as @using, or layout and partial-view references is source code for Razor. File.ReadAllText returns those instructions unchanged. Sending that text to XMLWorker produces literal Razor syntax, missing values, or parsing errors.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Static HTML saved with a .cshtml extension
If the file contains only final HTML and CSS, with no Razor directives or expressions, it can be read like any other local HTML file. The extension alone does not make it executable; the contents and the hosting context decide which path applies.
#1 Best Overall
How the conversion pipeline works
- For a Razor view, invoke the ASP.NET view engine with the correct model, view data, route data, HTTP context, services, layout, partials and encoding settings.
- Capture the rendered HTML string or stream.
- Create an iTextSharp
DocumentandPdfWriter. - Open the document and pass the rendered HTML to
XMLWorkerHelper.GetInstance().ParseXHtml. - Close and dispose the document, writer and streams, then inspect the PDF for unsupported markup, fonts and assets.
That separation is deliberate. The iText Knowledge Base explains that ASP.NET, MVC and Razor are HTML frameworks that iText/iTextSharp does not understand; obtaining framework-generated HTML is the application’s responsibility.
Case 1: convert a local file that is already static HTML
The following legacy iTextSharp/XMLWorker pattern reads a local file and writes a PDF. Adjust paths, encoding and resource handling for your application.
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
string htmlPath = @"C:templatesinvoice.cshtml";
string pdfPath = @"C:outputinvoice.pdf";
using (var htmlReader = new StreamReader(htmlPath))
using (var output = new FileStream(pdfPath, FileMode.Create, FileAccess.Write))
using (var document = new Document())
{
PdfWriter writer = PdfWriter.GetInstance(document, output);
document.Open();
XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, htmlReader);
document.Close();
}
This works only when htmlReader supplies final HTML. Use an explicit StreamReader encoding when the file is not UTF-8, for example new StreamReader(htmlPath, Encoding.UTF8, true). In production, validate paths, handle exceptions, and avoid allowing untrusted users to choose arbitrary files.
Case 2: render Razor first, then call XMLWorker
There is no single Razor-to-string helper that is interchangeable across classic ASP.NET MVC, Web Pages and ASP.NET Core. The exact rendering code depends on the framework and version. The framework-specific part should therefore be treated as pseudocode until adapted to your application:
Rank #2
// Framework-specific pseudocode:
string html = await RenderViewToStringAsync(
viewName: "Invoice",
model: invoice,
httpContext: currentHttpContext,
routeData: currentRouteData);
using (var output = new FileStream(pdfPath, FileMode.Create))
using (var document = new Document())
using (var htmlReader = new StringReader(html))
{
PdfWriter writer = PdfWriter.GetInstance(document, output);
document.Open();
XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, htmlReader);
document.Close();
}
In classic ASP.NET MVC, render the view through the MVC view engine while supplying a controller context, view data, temp data and model. In ASP.NET Core, use the registered IRazorViewEngine, an ActionContext, ViewDataDictionary and TempDataDictionary. Preserve the same request URL, culture, authentication state and dependency-injected services that the view expects. A view that relies on a layout, partial, tag helper, URL helper or localized resource will not render correctly without the corresponding context.
Do not run Razor by concatenating strings or by treating @ expressions as HTML. Rendering also performs HTML encoding and resolves conditionals, loops and model values. Capture the output only after the view has completed.
CSS, images and relative URLs
Stylesheets
XMLWorker is more capable than the old HTMLWorker, but its CSS support is not browser-level. The iText examples demonstrate inline CSS and absolutely linked stylesheets. Keep markup and CSS within the subset supported by the XMLWorker version in your project.
Images and fonts
A relative image or stylesheet URL may fail when HTML is supplied as a string because the parser may not know the document’s base directory. Use the XMLWorker overload and resource provider appropriate to your version, or convert important assets to resolvable absolute paths or data URLs. Verify file permissions, URL accessibility, MIME types and font availability in the deployment environment.
Browser-only features
XMLWorker does not execute JavaScript, perform layout like a browser, load client-side components, or evaluate Razor. CSS grid, flexbox, animations, SVG features and modern selectors may be ignored or rendered differently. Design a PDF-specific view with simple tables, explicit widths, print-friendly colors and embedded or registered fonts when fidelity matters.
Choosing the right approach
| Situation | Correct input to XMLWorker | Important caveat |
|---|---|---|
| Razor expressions, layouts or partials | HTML captured after view-engine rendering | A model and valid request/view context are required |
| Plain HTML in a .cshtml file | File stream or TextReader |
The extension is irrelevant; contents must already be final HTML |
| New application | Evaluate current iText and pdfHTML packages | Check current API and licensing terms before coding |
| Existing iTextSharp application | XMLWorker for a controlled legacy conversion | Plan for deprecated, end-of-life components and limited CSS |
iTextSharp and XMLWorker maintenance status
The current XMLWorker package metadata describes XMLWorker as deprecated and says iTextSharp is end-of-life, replaced by iText. That makes a legacy answer reasonable for maintaining an existing application, but a new project should evaluate the current iText/pdfHTML ecosystem and its license requirements. The package metadata notes that commercial licensing is available for software or services that cannot comply with AGPL terms; consult the current official package and licensing terms for your deployment.
Common failures and fixes
The PDF contains literal @Model or Razor directives
Cause: source .cshtml was read directly. Fix: render it through the appropriate Razor host, then pass only the resulting HTML to XMLWorker.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →“File not found” for a stylesheet or image
Cause: a relative URL has no usable base directory, or the worker process lacks permission. Fix: provide a correct resource provider/base path, use an absolute resolvable path, grant read access, and confirm the deployed file exists.
Rank #4
Missing CSS or broken layout
Cause: unsupported CSS, malformed HTML, or browser-only layout rules. Fix: validate and simplify the HTML, prefer tables and explicit dimensions, move critical rules inline, and test the exact XMLWorker version.
Images are blank
Cause: inaccessible URLs, unsupported formats, relative paths or authentication requirements. Fix: make assets available to the server, use supported image formats, resolve paths explicitly, and supply authenticated resources through a controlled resource strategy.
Razor rendering throws null-reference or service errors
Cause: the rendering context lacks the model, services, route data, culture, claims or view data supplied during a normal request. Fix: construct the same context your application uses and provide a complete model; do not substitute an unrelated generic view helper.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Conversion hangs or consumes excessive memory
Cause: very large HTML, huge images, recursive partials, slow resources or unbounded user input. Fix: impose input and output limits, avoid remote assets where possible, resize images, set request timeouts around rendering, dispose every stream, and log the failing view and asset.
Best Value
Testing checklist before production
- Render with real and empty models, long text, missing optional fields and localized data.
- Confirm layouts and partials resolve under the production deployment path.
- Test fonts, page breaks, tables, images, hyperlinks and non-ASCII characters.
- Test with the exact iTextSharp/XMLWorker package versions used in deployment.
- Inspect generated PDFs rather than assuming browser appearance equals PDF appearance.
- Keep untrusted HTML, file paths, URLs and CSS under strict validation and access controls.
Or skip the browser setup
If your goal is simply to capture a rendered web page rather than generate a PDF inside your ASP.NET process, ScreenshotNeo provides a website screenshot API and MCP server. It accepts a URL and returns PNG, JPEG, WebP or PDF. A single request can handle page capture without installing a browser locally:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for the complete API. Before capture it can accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP server exposes take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots. Sign up for the free plan.
Frequently Asked Questions
Can I pass a .cshtml filename directly to XMLWorker?
Only when the file already contains static, final HTML. A Razor source file must be rendered first.
Recommended Free Tools
Should I use HTMLWorker instead of XMLWorker?
For legacy iTextSharp, XMLWorker generally provides more capable HTML/CSS parsing. Neither parser is a browser or Razor engine.
Is iTextSharp suitable for a new project?
It is end-of-life according to current package metadata. Evaluate current iText/pdfHTML packages, APIs and licensing for new work.
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.

