Convert HTML to PDF in ASP.NET MVC Razor

A special case is when  the view you want to convert to PDF uses some values stored in ASP.NET Session. This values can be made available in the MVC view to when converted to PDF. When you convert an ASP.NET MVC URL, the converter will make a GET request to the URL in a new session and the values stored in the current ASP.NET Session are not available. The solution is to get the HTML code rendered by the MVC view in the current context of the MVC controller and to convert that HTML code to PDF giving the appropriate base URL. 

The sample code below demonstrates this solution. When the 'Convert This Page to PDF' button in the Index view is pressed the Index view itself is converted. When the 'Convert About Page to PDF' button in the Index view is pressed the About view in the same application is converted to PDF.

1. Source Code Example - MVC Controller C# Code

// See full demo source code and details at HiQPDF HTML to PDF .NET Library FAQs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using System.IO;
using HiQPdf;

namespace HiQPdfMvcRazorApplication.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";
            Session["MySessionVariable"] = "My Session Variable Value assigned in Index"; 
            return View();
        }

        public ActionResult About()
        {
            return View();
        }

        public string RenderViewAsString(string viewName, object model)
        {
            // create a string writer to receive the HTML code
            StringWriter stringWriter = new StringWriter();

            // get the view to render
            ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, null);
            // create a context to render a view based on a model
            ViewContext viewContext = new ViewContext(
                    ControllerContext,
                    viewResult.View,
                    new ViewDataDictionary(model),
                    new TempDataDictionary(),
                    stringWriter
                    );

            // render the view to a HTML code
            viewResult.View.Render(viewContext, stringWriter);

            // return the HTML code
            return stringWriter.ToString();
        }

        [HttpPost]
        public ActionResult ConvertThisPageToPdf()
        {
            // get the HTML code of this view
            string htmlToConvert = RenderViewAsString("Index", null);

            // the base URL to resolve relative images and css
            String thisPageUrl = this.ControllerContext.HttpContext.Request.Url.AbsoluteUri;
            String baseUrl = thisPageUrl.Substring(0, thisPageUrl.Length - "Home/ConvertThisPageToPdf".Length);

            // instantiate the HiQPdf HTML to PDF converter
            HtmlToPdf htmlToPdfConverter = new HtmlToPdf();

            // hide the button in the created PDF
            htmlToPdfConverter.HiddenHtmlElements = new string[] { "#convertThisPageButtonDiv" };

            // render the HTML code as PDF in memory
            byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htmlToConvert, baseUrl);

            // send the PDF file to browser
            FileResult fileResult = new FileContentResult(pdfBuffer, "application/pdf");
            fileResult.FileDownloadName = "ThisMvcViewToPdf.pdf";

            return fileResult;
        }

        [HttpPost]
        public ActionResult ConvertAboutPageToPdf()
        {
            // get the About view HTML code
            string htmlToConvert = RenderViewAsString("About", null);

            // the base URL to resolve relative images and css
            String thisPageUrl = this.ControllerContext.HttpContext.Request.Url.AbsoluteUri;
            String baseUrl = thisPageUrl.Substring(0, thisPageUrl.Length - "Home/ConvertAboutPageToPdf".Length);

            // instantiate the HiQPdf HTML to PDF converter
            HtmlToPdf htmlToPdfConverter = new HtmlToPdf();

            // render the HTML code as PDF in memory
            byte[] pdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htmlToConvert, baseUrl);

            // send the PDF file to browser
            FileResult fileResult = new FileContentResult(pdfBuffer, "application/pdf");
            fileResult.FileDownloadName = "AboutMvcViewToPdf.pdf";

            return fileResult;
        }
    }
}


2. Source Code Example - Index View Razor Code

@{
    ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<p>
    To learn more about ASP.NET MVC visit ASP.NET MVC Website
</p>
<br />
@using (Html.BeginForm("ConvertThisPageToPdf", "Home", FormMethod.Post, new { id = "convertForm" }))
{
    <div id="convertThisPageButtonDiv">
        <input type="submit" value="Convert
                        This Page To PDF" 
                            />
    </div>
}
<br />
@using (Html.BeginForm("ConvertAboutPageToPdf", "Home", FormMethod.Post, new { id = "convertForm" }))
{
    <div id="convertAboutPageButtonDiv">
        <input type="submit" value="Convert
                        About Page To PDF" 
                            />
    </div>
}
<br />
<br />
<h1>
    @Session["MySessionVariable"].ToString()</h1>
<br />
<br />
<img alt="" 
            style="height: 100px" 
                            src="/Images/banner.png" />


Source Code Example - Index View MVC Code

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site
    .Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>
        <%: (String)ViewBag.Message %></h2>
    <p>
        To learn more about ASP.NET MVC visit ASP.NET MVC Website
    </p>
    <br />
    <form action="/Home/ConvertThisPageToPdf" id="convertThisPageForm" method="post">
    <div id="convertThisPageButtonDiv">
        <input type="submit" value="Convert
                        This Page To PDF" 
                            />
    </div>
    </form>
    <br />
    <form action="/Home/ConvertAboutPageToPdf" id="convertAboutPageForm"
                    method="post">
    <div id="convertAboutPageButtonDiv">
        <input type="submit" value="Convert
                        About Page To PDF" 
                            />
    </div>
    </form>
    <br />
    <br />
    <h1>
        <%: Session["MySessionVariable"].ToString()%></h1>
    <br />
    <br />
    <img alt="" 
                style="height: 100px" 
                                src="/Images/banner.png" />
</asp:Content>