How to Convert HTML to PDF Behind Login Authentication Forms

The best way to deal with logins is to avoid them if possible, and render html directly from a file or a string.

Best Practices

IronPDF supports TLS network authentication (username and password) which is extremely secure and .NET web apps can easily support it: https://ironpdf.com/object-reference/api/IronPdf.ChromeHttpLoginCredentials.html

The best practice is to use System.Net.WebClient or HttpClient to download the HTML and any assets. This fully supports headers, logins, and everything else you may require. Once downloaded to memory or the disk, IronPDF can turn your HTML into a PDF. Assets such as stylesheets and images can be discovered using the HtmlAgilityPack and then downloaded using the System.Net.WebClient as well.

string html;
using (WebClient client = new WebClient()) {
    html = client.DownloadString("http://www.google.com");
}
HtmlDocument doc = new HtmlDocument();        
doc.LoadHtml(html);
foreach(HtmlNode img in doc.DocumentNode.SelectNodes("//img")) {
    Console.WriteLine(img.GetAttributeValue("src", null));
}
string html;
using (WebClient client = new WebClient()) {
    html = client.DownloadString("http://www.google.com");
}
HtmlDocument doc = new HtmlDocument();        
doc.LoadHtml(html);
foreach(HtmlNode img in doc.DocumentNode.SelectNodes("//img")) {
    Console.WriteLine(img.GetAttributeValue("src", null));
}
Dim html As String
Using client As New WebClient()
	html = client.DownloadString("http://www.google.com")
End Using
Dim doc As New HtmlDocument()
doc.LoadHtml(html)
For Each img As HtmlNode In doc.DocumentNode.SelectNodes("//img")
	Console.WriteLine(img.GetAttributeValue("src", Nothing))
Next img
VB   C#

Note that any relative Url can be rebased to an absolute url using an overloaded constructor for the System.Uri class. To rebase any relative paths in an entire html document add a

tab to the header using HtmlAgilityPack. Example.

Login using Network Authentication

Most ASP.Net applications support network authentication which is more reliable than html form posting,

var uri = new Uri("http://localhost:51169/Invoice");

var renderer = new ChromePdfRenderer
{
    PrintOptions = new ChromePdfRenderOptions()
    {
        MarginTop = 50,
        MarginBottom = 50,
        TextHeader = new TextHeaderFooter()
        {
            CenterText = "{pdf-title}",
            DrawDividerLine = true,
            FontSize = 16
        },
        TextFooter = new TextHeaderFooter()
        {
            LeftText = "{date} {time}",
            RightText = "Page {page} of {total-pages}",
            DrawDividerLine = true,
            FontSize = 14
        },
        CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
    },

    // setting login credentials to bypass basic authentication

    LoginCredentials = new HttpLoginCredentials()
    {
        NetworkUsername = "testUser",
        NetworkPassword = "testPassword"
    }
};

var renderer = urlToPdf.RenderUrlAsPdf(uri);

pdf.SaveAs(Path.Combine(Directory.GetCurrentDirectory(), "UrlToPdfExample.Pdf"));
var uri = new Uri("http://localhost:51169/Invoice");

var renderer = new ChromePdfRenderer
{
    PrintOptions = new ChromePdfRenderOptions()
    {
        MarginTop = 50,
        MarginBottom = 50,
        TextHeader = new TextHeaderFooter()
        {
            CenterText = "{pdf-title}",
            DrawDividerLine = true,
            FontSize = 16
        },
        TextFooter = new TextHeaderFooter()
        {
            LeftText = "{date} {time}",
            RightText = "Page {page} of {total-pages}",
            DrawDividerLine = true,
            FontSize = 14
        },
        CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
    },

    // setting login credentials to bypass basic authentication

    LoginCredentials = new HttpLoginCredentials()
    {
        NetworkUsername = "testUser",
        NetworkPassword = "testPassword"
    }
};

var renderer = urlToPdf.RenderUrlAsPdf(uri);

pdf.SaveAs(Path.Combine(Directory.GetCurrentDirectory(), "UrlToPdfExample.Pdf"));
Dim uri As New Uri("http://localhost:51169/Invoice")

Dim renderer = New ChromePdfRenderer With {
	.PrintOptions = New ChromePdfRenderOptions() With {
		.MarginTop = 50,
		.MarginBottom = 50,
		.TextHeader = New TextHeaderFooter() With {
			.CenterText = "{pdf-title}",
			.DrawDividerLine = True,
			.FontSize = 16
		},
		.TextFooter = New TextHeaderFooter() With {
			.LeftText = "{date} {time}",
			.RightText = "Page {page} of {total-pages}",
			.DrawDividerLine = True,
			.FontSize = 14
		},
		.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
	},
	.LoginCredentials = New HttpLoginCredentials() With {
		.NetworkUsername = "testUser",
		.NetworkPassword = "testPassword"
	}
}

Dim renderer = urlToPdf.RenderUrlAsPdf(uri)

pdf.SaveAs(Path.Combine(Directory.GetCurrentDirectory(), "UrlToPdfExample.Pdf"))
VB   C#

Login using an HTML Form

To log in by sending data to a HTML form may also be achieved using the HttpLoginCredentials class as in the previous example.

Instead of specifying a username and password, you may choose to send CustomPostVariables, or LoginFormPostVariables.

See IronPDF's ChromeHttpLoginCredentials API.

Please Consider:

  • The login data must be posted to the url specified in the HTML form's ACTION attribute. This should be set as the *LoginFormUrl* attribute of the HttpLoginCredentials. This may vary from the url you actually want to render as a PDF.
  • The data to be sent should represent every input and textarea in the HTML form. The name attributes define the name of each variable (not the id as is commonly misunderstood).
  • Some websites may active protect against this kind of machine login.

MVC

The following work around allows a dot net MVC view to be rendered programmatically to a string - which is very useful in avoiding MVC logins yet rendering a view faithfully.

public static string RenderPartialViewToString(this Controller controller, string viewPath, object model = null)
{
    try
    {
        var context = controller.ControllerContext;

        controller.ViewData.Model = model;

        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(context, viewPath);

            if (viewResult.View == null)
            {
                throw new Exception($"Partial view {viewPath} could not be found.");
            }

            var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData,context.Controller.TempData, sw);

            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(context, viewResult.View);

            return sw.GetStringBuilder().ToString();
        }
    }
    catch (Exception ex)
    {
        return ex.Message;
    }
}
public static string RenderPartialViewToString(this Controller controller, string viewPath, object model = null)
{
    try
    {
        var context = controller.ControllerContext;

        controller.ViewData.Model = model;

        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(context, viewPath);

            if (viewResult.View == null)
            {
                throw new Exception($"Partial view {viewPath} could not be found.");
            }

            var viewContext = new ViewContext(context, viewResult.View, context.Controller.ViewData,context.Controller.TempData, sw);

            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(context, viewResult.View);

            return sw.GetStringBuilder().ToString();
        }
    }
    catch (Exception ex)
    {
        return ex.Message;
    }
}
<System.Runtime.CompilerServices.Extension> _
Public Function RenderPartialViewToString(ByVal controller As Controller, ByVal viewPath As String, Optional ByVal model As Object = Nothing) As String
	Try
		Dim context = controller.ControllerContext

		controller.ViewData.Model = model

		Using sw = New StringWriter()
			Dim viewResult = ViewEngines.Engines.FindPartialView(context, viewPath)

			If viewResult.View Is Nothing Then
				Throw New Exception($"Partial view {viewPath} could not be found.")
			End If

			Dim viewContext As New ViewContext(context, viewResult.View, context.Controller.ViewData,context.Controller.TempData, sw)

			viewResult.View.Render(viewContext, sw)
			viewResult.ViewEngine.ReleaseView(context, viewResult.View)

			Return sw.GetStringBuilder().ToString()
		End Using
	Catch ex As Exception
		Return ex.Message
	End Try
End Function
VB   C#