IronPDF How-Tos CSHTML to PDF (MVC Core) How to Convert Views to PDFs in ASP.NET Core MVC Chaknith Bin Updated:June 22, 2025 A View is a component in the ASP.NET framework used for generating HTML markup in web applications. It is a part of the Model-View-Controller (MVC) pattern, commonly used in ASP.NET MVC and ASP.NET Core MVC applications. Views are responsible for presenting data to the user by rendering HTML content dynamically. ASP.NET Core Web App MVC (Model-View-Controller) is a web application provided by Microsoft for building web applications using ASP.NET Core. Model: Represents data and business logic, manages data interactions, and communicates with data sources. View: Presents the user interface, focuses on displaying data, and renders information to the user. Controller: Handles user input, responds to requests, communicates with the Model, and orchestrates interactions between the Model and the View. IronPDF simplifies the process of creating PDF files from Views within an ASP.NET Core MVC project. This makes PDF generation easy and direct in ASP.NET Core MVC. How to Convert Views to PDFs in ASP.NET Core MVC Download the C# library for converting Views to PDFs in ASP.NET Core MVC Add a model class for the data Edit the "HomeController.cs" file and use the RenderRazorViewToPdf method Create a new View and edit the ".cshtml" file to render the PDF Download the sample project for a quick start IronPDF Extension Package The IronPdf.Extensions.Mvc.Core package is an extension of the main IronPdf package. Both the IronPdf.Extensions.Mvc.Core and IronPdf packages are needed to render Views to PDF documents in an ASP.NET Core MVC. Install-Package IronPdf.Extensions.Mvc.Core Install with NuGet Install-Package IronPdf.Extensions.Mvc.Core nuget.org/packages/IronPdf.Extensions.Mvc.Core/ Render Views to PDFs You'll need an ASP.NET Core Web App (Model-View-Controller) project to convert Views into PDF files. Add a Model Class Navigate to the "Models" folder. Create a new C# class file named "Person." This class will act as a model to represent individual data. Use the following code snippet: :path=/static-assets/pdf/content-code-examples/how-to/cshtml-to-pdf-mvc-core-model.cs namespace ViewToPdfMVCCoreSample.Models { public class Person { public int Id { get; set; } public string Name { get; set; } public string Title { get; set; } public string Description { get; set; } } } Namespace ViewToPdfMVCCoreSample.Models Public Class Person Public Property Id() As Integer Public Property Name() As String Public Property Title() As String Public Property Description() As String End Class End Namespace $vbLabelText $csharpLabel Edit the Controller Navigate to the "Controllers" folder and open the "HomeController" file. We are going to make changes only to the HomeController and add the "Persons" action. Please refer to the code below for guidance: The code below first instantiates the ChromePdfRenderer class, passing an IRazorViewRenderer, the path to our "Persons.cshtml," and the List that contains the required data to the RenderRazorViewToPdf method. Users can utilize RenderingOptions to access a range of features, such as adding custom text, including HTML headers and footers in the resulting PDF, defining custom margins, and applying page numbers. Please noteThe PDF document can be viewed in the browser using the following code: File(pdf.BinaryData, "application/pdf"). However, downloading the PDF after viewing it in the browser results in a damaged PDF document. using IronPdf.Extensions.Mvc.Core; using Microsoft.AspNetCore.Mvc; using System.Diagnostics; using ViewToPdfMVCCoreSample.Models; namespace ViewToPdfMVCCoreSample.Controllers { public class HomeController : Controller { private readonly ILogger<HomeController> _logger; private readonly IRazorViewRenderer _viewRenderService; private readonly IHttpContextAccessor _httpContextAccessor; public HomeController(ILogger<HomeController> logger, IRazorViewRenderer viewRenderService, IHttpContextAccessor httpContextAccessor) { _logger = logger; _viewRenderService = viewRenderService; _httpContextAccessor = httpContextAccessor; } public IActionResult Index() { return View(); } public async Task<IActionResult> Persons() { // Example list of persons var persons = new List<Person> { new Person { Name = "Alice", Title = "Mrs.", Description = "Software Engineer" }, new Person { Name = "Bob", Title = "Mr.", Description = "Software Engineer" }, new Person { Name = "Charlie", Title = "Mr.", Description = "Software Engineer" } }; // Check if the request method is POST if (_httpContextAccessor.HttpContext.Request.Method == HttpMethod.Post.Method) { // Create a new PDF renderer ChromePdfRenderer renderer = new ChromePdfRenderer(); // Render View to PDF document PdfDocument pdf = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons); Response.Headers.Add("Content-Disposition", "inline"); // Output PDF document return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf"); } return View(persons); } public IActionResult Privacy() { return View(); } [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } } } using IronPdf.Extensions.Mvc.Core; using Microsoft.AspNetCore.Mvc; using System.Diagnostics; using ViewToPdfMVCCoreSample.Models; namespace ViewToPdfMVCCoreSample.Controllers { public class HomeController : Controller { private readonly ILogger<HomeController> _logger; private readonly IRazorViewRenderer _viewRenderService; private readonly IHttpContextAccessor _httpContextAccessor; public HomeController(ILogger<HomeController> logger, IRazorViewRenderer viewRenderService, IHttpContextAccessor httpContextAccessor) { _logger = logger; _viewRenderService = viewRenderService; _httpContextAccessor = httpContextAccessor; } public IActionResult Index() { return View(); } public async Task<IActionResult> Persons() { // Example list of persons var persons = new List<Person> { new Person { Name = "Alice", Title = "Mrs.", Description = "Software Engineer" }, new Person { Name = "Bob", Title = "Mr.", Description = "Software Engineer" }, new Person { Name = "Charlie", Title = "Mr.", Description = "Software Engineer" } }; // Check if the request method is POST if (_httpContextAccessor.HttpContext.Request.Method == HttpMethod.Post.Method) { // Create a new PDF renderer ChromePdfRenderer renderer = new ChromePdfRenderer(); // Render View to PDF document PdfDocument pdf = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons); Response.Headers.Add("Content-Disposition", "inline"); // Output PDF document return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf"); } return View(persons); } public IActionResult Privacy() { return View(); } [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } } } Imports IronPdf.Extensions.Mvc.Core Imports Microsoft.AspNetCore.Mvc Imports System.Diagnostics Imports ViewToPdfMVCCoreSample.Models Namespace ViewToPdfMVCCoreSample.Controllers Public Class HomeController Inherits Controller Private ReadOnly _logger As ILogger(Of HomeController) Private ReadOnly _viewRenderService As IRazorViewRenderer Private ReadOnly _httpContextAccessor As IHttpContextAccessor Public Sub New(ByVal logger As ILogger(Of HomeController), ByVal viewRenderService As IRazorViewRenderer, ByVal httpContextAccessor As IHttpContextAccessor) _logger = logger _viewRenderService = viewRenderService _httpContextAccessor = httpContextAccessor End Sub Public Function Index() As IActionResult Return View() End Function Public Async Function Persons() As Task(Of IActionResult) ' Example list of persons 'INSTANT VB NOTE: The local variable persons was renamed since Visual Basic will not allow local variables with the same name as their enclosing function or property: Dim persons_Conflict = New List(Of Person) From { New Person With { .Name = "Alice", .Title = "Mrs.", .Description = "Software Engineer" }, New Person With { .Name = "Bob", .Title = "Mr.", .Description = "Software Engineer" }, New Person With { .Name = "Charlie", .Title = "Mr.", .Description = "Software Engineer" } } ' Check if the request method is POST If _httpContextAccessor.HttpContext.Request.Method = HttpMethod.Post.Method Then ' Create a new PDF renderer Dim renderer As New ChromePdfRenderer() ' Render View to PDF document Dim pdf As PdfDocument = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons_Conflict) Response.Headers.Add("Content-Disposition", "inline") ' Output PDF document Return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf") End If Return View(persons_Conflict) End Function Public Function Privacy() As IActionResult Return View() End Function <ResponseCache(Duration := 0, Location := ResponseCacheLocation.None, NoStore := True)> Public Function [Error]() As IActionResult Return View(New ErrorViewModel With {.RequestId = If(Activity.Current?.Id, HttpContext.TraceIdentifier)}) End Function End Class End Namespace $vbLabelText $csharpLabel After using the RenderRazorViewToPdf method, you'll receive a PdfDocument object that's open to further enhancements and modifications. You have the flexibility to convert the PDF to PDF/A or PDF/UA formats, add your digital signature to the generated PDF, or merge and split PDF documents as needed. Additionally, the library allows you to rotate pages, insert annotations or bookmarks, and imprint unique watermarks onto your PDF files. Add a View Right-click on the newly added Person action and select "Add View." Choose "Razor View" for the new Scaffolded item. Select the "List" template and the "Person" model class. This will create a .cshtml file named "Persons." Navigate to the "Views" folder -> "Home" folder -> "Persons.cshtml" file. To add a button that invokes the "Persons" action, use the code below: @using (Html.BeginForm("Persons", "Home", FormMethod.Post)) { <input type="submit" value="Print Person" /> } @using (Html.BeginForm("Persons", "Home", FormMethod.Post)) { <input type="submit" value="Print Person" /> } HTML Add a Section to the Top Navigation Bar In the same "Views" folder navigate to the "Shared" folder -> _Layout.cshtml. Place the "Person" navigation item after "Home". Make sure the value for the asp-action attribute matches exactly with our file name, which in this case is "Persons". <header> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <div class="container-fluid"> <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">ViewToPdfMVCCoreSample</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between"> <ul class="navbar-nav flex-grow-1"> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Persons">Person</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> </li> </ul> </div> </div> </nav> </header> <header> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <div class="container-fluid"> <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">ViewToPdfMVCCoreSample</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between"> <ul class="navbar-nav flex-grow-1"> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Persons">Person</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> </li> </ul> </div> </div> </nav> </header> HTML Edit Program.cs File We will be registering the IHttpContextAccessor and IRazorViewRenderer interface to the dependency injection (DI) container. Please check the code below for your reference. using IronPdf.Extensions.Mvc.Core; using Microsoft.AspNetCore.Mvc.ViewFeatures; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>(); // Register IRazorViewRenderer here builder.Services.AddSingleton<IRazorViewRenderer, RazorViewRenderer>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); using IronPdf.Extensions.Mvc.Core; using Microsoft.AspNetCore.Mvc.ViewFeatures; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>(); // Register IRazorViewRenderer here builder.Services.AddSingleton<IRazorViewRenderer, RazorViewRenderer>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); Imports IronPdf.Extensions.Mvc.Core Imports Microsoft.AspNetCore.Mvc.ViewFeatures Private builder = WebApplication.CreateBuilder(args) ' Add services to the container. builder.Services.AddControllersWithViews() builder.Services.AddSingleton(Of IHttpContextAccessor, HttpContextAccessor)() builder.Services.AddSingleton(Of ITempDataProvider, CookieTempDataProvider)() ' Register IRazorViewRenderer here builder.Services.AddSingleton(Of IRazorViewRenderer, RazorViewRenderer)() Dim app = builder.Build() ' Configure the HTTP request pipeline. If Not app.Environment.IsDevelopment() Then app.UseExceptionHandler("/Home/Error") ' The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts() End If app.UseHttpsRedirection() app.UseStaticFiles() app.UseRouting() app.UseAuthorization() app.MapControllerRoute(name:= "default", pattern:= "{controller=Home}/{action=Index}/{id?}") app.Run() $vbLabelText $csharpLabel Run the Project This will show you how to run the project and generate a PDF document. Download ASP.NET Core MVC Project You can download the complete code for this guide. It comes as a zipped file that you can open in Visual Studio as an ASP.NET Core Web App (Model-View-Controller) project. Download the ASP.NET Core MVC Sample Project Ready to see what else you can do? Check out our tutorial page here: Convert PDFs Frequently Asked Questions How can I convert CSHTML to PDF in ASP.NET Core MVC? You can use IronPDF's `RenderRazorViewToPdf` method to convert CSHTML files to PDFs within an ASP.NET Core MVC project. What steps are required to set up PDF generation in an ASP.NET Core MVC project? To set up PDF generation, download the IronPDF library via NuGet, create a model class, edit the HomeController to use the `RenderRazorViewToPdf` method, and set up dependency injection for `IHttpContextAccessor` and `IRazorViewRenderer` in the 'Program.cs' file. Why is dependency injection necessary for PDF conversion in ASP.NET Core? Dependency injection for `IHttpContextAccessor` and `IRazorViewRenderer` is necessary to properly render Views as PDFs, ensuring that the Razor View rendering context is correctly established. Can I customize the PDF output when converting Views in ASP.NET Core MVC? Yes, using IronPDF, you can customize the PDF output by adjusting headers, footers, margins, and other settings within the `RenderRazorViewToPdf` method. What is the role of the `RenderRazorViewToPdf` method in PDF conversion? The `RenderRazorViewToPdf` method is essential for converting Razor Views to PDF documents, providing options to customize the PDF's appearance and content. How can I ensure my ASP.NET Core MVC project supports PDF conversion? Ensure your project supports PDF conversion by installing the IronPdf.Extensions.Mvc.Core package and configuring the necessary services and models within your project. Is it possible to add interactive elements to PDFs generated from Views? Yes, after generating a PDF using IronPDF, you can add interactive elements such as forms, links, and bookmarks to enhance user interaction within the document. Where can I find a sample project for converting Views to PDFs? You can download a sample project provided in the guide, which demonstrates the complete setup for converting Views to PDFs in an ASP.NET Core Web App. How do I install IronPDF in my ASP.NET Core MVC project? Install IronPDF by using the NuGet package manager with the command: Install-Package IronPdf.Extensions.Mvc.Core. Chaknith Bin Chat with engineering team now Software Engineer Chaknith works on IronXL and IronBarcode. He has deep expertise in C# and .NET, helping improve the software and support customers. His insights from user interactions contribute to better products, documentation, and overall experience. Reviewed by Jeffrey T. Fritz Principal Program Manager - .NET Community Team Jeff is also a Principal Program Manager for the .NET and Visual Studio teams. He is the executive producer of the .NET Conf virtual conference series and hosts 'Fritz and Friends' a live stream for developers that airs twice weekly where he talks tech and writes code together with viewers. Jeff writes workshops, presentations, and plans content for the largest Microsoft developer events including Microsoft Build, Microsoft Ignite, .NET Conf, and the Microsoft MVP Summit Ready to Get Started? Free NuGet Download Total downloads: 15,030,178 View Licenses