Jak zarządzać logowaniem i uwierzytelnianiem przy użyciu języka C#

Konwertuj HTML do PDF za uwierzytelnieniem logowania w C

This article was translated from English: Does it need improvement?
Translated
View the article in English

Aby przekonwertować HTML na PDF za pomocą uwierzytelniania logowania w języku C#, należy użyć funkcji ChromeHttpLoginCredentials biblioteki IronPDF do uwierzytelniania sieciowego lub pobrać plik HTML za pomocą funkcji HttpClient przed konwersją. To podejście skutecznie obsługuje zarówno uwierzytelnienie sieciowe, jak i logowania w formularzach HTML.

Quickstart: Konwertuj HTML na PDF za logowaniem z IronPDF

Przekonwertuj strony HTML na PDF za formularzami logowania, używając API IronPDF. W niniejszym przewodniku przedstawiono ChromeHttpLoginCredentials w celu uwierzytelniania i pobierania treści chronionych. Obsługuj zarówno uwierzytelnienie sieciowe, jak i logowania w formularzach HTML z prostymi przykładami kodu.

  1. Install IronPDF with NuGet Package Manager

    PM > Install-Package IronPdf
  2. Skopiuj i uruchom ten fragment kodu.

    new ChromePdfRenderer { LoginCredentials = new ChromeHttpLoginCredentials("username","password") }
        .RenderUrlAsPdf("https://example.com/protected")
        .SaveAs("secure.pdf");
  3. Wdrożenie do testowania w środowisku produkcyjnym

    Rozpocznij używanie IronPDF w swoim projekcie już dziś z darmową wersją próbną

    arrow pointer


Jakie są najlepsze praktyki obsługi uwierzytelniania logowania?

IronPDF wspiera sieciowe uwierzytelnienie TLS (nazwa użytkownika i hasło) poprzez ChromeHttpLoginCredentials API. Dla kompleksowych wskazówek dotyczących różnych scenariuszy logowania, zobacz poradnik logowań TLS Website & System.

Zalecanym podejściem jest użycie System.Net.WebClient lub HttpClient do pobrania kodu HTML i zasobów. Ta metoda wspiera nagłówki, logowania i inne wymagania. Po pobraniu do pamięci lub na dysk, IronPDF konwertuje HTML do PDF. Wyodrębnij zasoby, takie jak arkusze stylów i obrazy, za pomocą HtmlAgilityPack, a następnie pobierz je za pomocą System.Net.WebClient.

// Download HTML content from a URL with authentication
string html;
using (WebClient client = new WebClient()) 
{
    // Add authentication headers if needed
    client.Headers.Add("Authorization", "Bearer " + accessToken);

    // Download the HTML string
    html = client.DownloadString("http://www.example.com/protected-content");
}

// Load the HTML into an HtmlDocument for parsing
HtmlDocument doc = new HtmlDocument();        
doc.LoadHtml(html);

// Extract all image sources for downloading
foreach(HtmlNode img in doc.DocumentNode.SelectNodes("//img")) 
{
    string imgSrc = img.GetAttributeValue("src", null);
    Console.WriteLine($"Found image: {imgSrc}");

    // Download each image asset
    if (!string.IsNullOrEmpty(imgSrc))
    {
        string fileName = Path.GetFileName(imgSrc);
        client.DownloadFile(imgSrc, fileName);
    }
}

// Convert the downloaded HTML to PDF
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("authenticated-content.pdf");
// Download HTML content from a URL with authentication
string html;
using (WebClient client = new WebClient()) 
{
    // Add authentication headers if needed
    client.Headers.Add("Authorization", "Bearer " + accessToken);

    // Download the HTML string
    html = client.DownloadString("http://www.example.com/protected-content");
}

// Load the HTML into an HtmlDocument for parsing
HtmlDocument doc = new HtmlDocument();        
doc.LoadHtml(html);

// Extract all image sources for downloading
foreach(HtmlNode img in doc.DocumentNode.SelectNodes("//img")) 
{
    string imgSrc = img.GetAttributeValue("src", null);
    Console.WriteLine($"Found image: {imgSrc}");

    // Download each image asset
    if (!string.IsNullOrEmpty(imgSrc))
    {
        string fileName = Path.GetFileName(imgSrc);
        client.DownloadFile(imgSrc, fileName);
    }
}

// Convert the downloaded HTML to PDF
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("authenticated-content.pdf");
Imports System.Net
Imports HtmlAgilityPack
Imports IronPdf

' Download HTML content from a URL with authentication
Dim html As String
Using client As New WebClient()
    ' Add authentication headers if needed
    client.Headers.Add("Authorization", "Bearer " & accessToken)

    ' Download the HTML string
    html = client.DownloadString("http://www.example.com/protected-content")
End Using

' Load the HTML into an HtmlDocument for parsing
Dim doc As New HtmlDocument()
doc.LoadHtml(html)

' Extract all image sources for downloading
For Each img As HtmlNode In doc.DocumentNode.SelectNodes("//img")
    Dim imgSrc As String = img.GetAttributeValue("src", Nothing)
    Console.WriteLine($"Found image: {imgSrc}")

    ' Download each image asset
    If Not String.IsNullOrEmpty(imgSrc) Then
        Dim fileName As String = Path.GetFileName(imgSrc)
        Using client As New WebClient()
            client.DownloadFile(imgSrc, fileName)
        End Using
    End If
Next

' Convert the downloaded HTML to PDF
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("authenticated-content.pdf")
$vbLabelText   $csharpLabel

Zwróć uwagęZmień adresy URL względne na bezwzględne, używając przeciążonego konstruktora System.Uri. Aby zmienić bazę wszystkich ścieżek względnych w dokumencie HTML, dodaj tag <base> do nagłówka za pomocą HtmlAgilityPack. Przykład. Więcej informacji na temat obsługi URL-i i zasobów znajdziesz w przewodniku Base URLs & Asset Encoding.

Dłączego powinienem najpierw pobrać zawartość HTML?

Pobieranie zawartości HTML przed konwersją oferuje kilka korzyści:

  1. Pełna kontrola: Modyfikuj HTML, naprawiaj uszkodzone linki lub wstawiaj tokeny uwierzytelniania przed konwersją
  2. Zarządzanie zasobami: Pobieraj i przechowuj zewnętrzne zasoby, takie jak obrazy, CSS i pliki JavaScript
  3. Elastyczność uwierzytelniania: Używaj dowolnego mechanizmu uwierzytelniania .NET, w tym OAuth, tokenów JWT lub niestandardowych nagłówków
  4. Wydajność: Przechowuj często dostępne treści, aby zmniejszyć obciążenie serwera
  5. Debugowanie: Sprawdź dokładny HTML przetwarzany w celu rozwiązania problemów

W przypadku złożonych scenariuszy uwierzytelniania obejmujących ciasteczka i sesje, zobacz przewodnik Cookies, który tłumaczy zarządzanie stanem uwierzytelnienia w trakcie konwersji PDF.

Jak obsługiwać zasoby takie jak obrazy i arkusze stylów?

Podczas konwersji uwierzytelnionych stron, zewnętrzne zasoby często wymagają tego samego uwierzytelnienia. Oto kompleksowe podejście z wykorzystaniem HttpClient:

public async Task<string> DownloadAuthenticatedHtmlWithAssets(string url, string authToken)
{
    using (var client = new HttpClient())
    {
        // Set authentication header
        client.DefaultRequestHeaders.Authorization = 
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authToken);

        // Download the main HTML
        string html = await client.GetStringAsync(url);

        // Parse HTML to find assets
        var doc = new HtmlDocument();
        doc.LoadHtml(html);

        // Create a base URI for resolving relative paths
        var baseUri = new Uri(url);

        // Download CSS files
        var cssLinks = doc.DocumentNode.SelectNodes("//link[@rel='stylesheet']");
        if (cssLinks != null)
        {
            foreach (var link in cssLinks)
            {
                string href = link.GetAttributeValue("href", "");
                if (!string.IsNullOrEmpty(href))
                {
                    var cssUri = new Uri(baseUri, href);
                    string cssContent = await client.GetStringAsync(cssUri);

                    // Embed CSS directly in the HTML
                    var styleNode = doc.CreateElement("style");
                    styleNode.InnerHtml = cssContent;
                    doc.DocumentNode.SelectSingleNode("//head").AppendChild(styleNode);

                    // Remove the external link
                    link.Remove();
                }
            }
        }

        // Return the modified HTML with embedded assets
        return doc.DocumentNode.OuterHtml;
    }
}
public async Task<string> DownloadAuthenticatedHtmlWithAssets(string url, string authToken)
{
    using (var client = new HttpClient())
    {
        // Set authentication header
        client.DefaultRequestHeaders.Authorization = 
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authToken);

        // Download the main HTML
        string html = await client.GetStringAsync(url);

        // Parse HTML to find assets
        var doc = new HtmlDocument();
        doc.LoadHtml(html);

        // Create a base URI for resolving relative paths
        var baseUri = new Uri(url);

        // Download CSS files
        var cssLinks = doc.DocumentNode.SelectNodes("//link[@rel='stylesheet']");
        if (cssLinks != null)
        {
            foreach (var link in cssLinks)
            {
                string href = link.GetAttributeValue("href", "");
                if (!string.IsNullOrEmpty(href))
                {
                    var cssUri = new Uri(baseUri, href);
                    string cssContent = await client.GetStringAsync(cssUri);

                    // Embed CSS directly in the HTML
                    var styleNode = doc.CreateElement("style");
                    styleNode.InnerHtml = cssContent;
                    doc.DocumentNode.SelectSingleNode("//head").AppendChild(styleNode);

                    // Remove the external link
                    link.Remove();
                }
            }
        }

        // Return the modified HTML with embedded assets
        return doc.DocumentNode.OuterHtml;
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports HtmlAgilityPack

Public Class HtmlDownloader
    Public Async Function DownloadAuthenticatedHtmlWithAssets(url As String, authToken As String) As Task(Of String)
        Using client As New HttpClient()
            ' Set authentication header
            client.DefaultRequestHeaders.Authorization = New System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", authToken)

            ' Download the main HTML
            Dim html As String = Await client.GetStringAsync(url)

            ' Parse HTML to find assets
            Dim doc As New HtmlDocument()
            doc.LoadHtml(html)

            ' Create a base URI for resolving relative paths
            Dim baseUri As New Uri(url)

            ' Download CSS files
            Dim cssLinks = doc.DocumentNode.SelectNodes("//link[@rel='stylesheet']")
            If cssLinks IsNot Nothing Then
                For Each link In cssLinks
                    Dim href As String = link.GetAttributeValue("href", "")
                    If Not String.IsNullOrEmpty(href) Then
                        Dim cssUri As New Uri(baseUri, href)
                        Dim cssContent As String = Await client.GetStringAsync(cssUri)

                        ' Embed CSS directly in the HTML
                        Dim styleNode = doc.CreateElement("style")
                        styleNode.InnerHtml = cssContent
                        doc.DocumentNode.SelectSingleNode("//head").AppendChild(styleNode)

                        ' Remove the external link
                        link.Remove()
                    End If
                Next
            End If

            ' Return the modified HTML with embedded assets
            Return doc.DocumentNode.OuterHtml
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

Jakie narzędzia pomagają z parsowaniem HTML?

HtmlAgilityPack jest najpopularniejszą biblioteką do parsowania HTML dla .NET, ale istnieją alternatywy:

  1. HtmlAgilityPack: Najlepsza do ogólnego parsowania i manipulacji HTML
  2. AngleSharp: Nowoczesny, zgodny ze standardami parser HTML z obsługą selektorów CSS
  3. CsQuery: Składnia podobna do jQuery dla programistów C# zaznajomionych z jQuery
  4. Regular Expressions: Do prostych zadań ekstrakcji (niezalecane do skomplikówanego HTML)

ChromeHttpLoginCredentials

Jak zalogować się używając uwierzytelnienia sieciowego?

Większość aplikacji ASP.NET obsługuje uwierzytelnienie sieciowe, które jest bardziej niezawodne niż wysyłanie formularza HTML. IronPDF zapewnia wbudowaną obsługę uwierzytelniania podstawowego, skróconego i NTLM poprzez klasę ChromeHttpLoginCredentials. W celu dodatkowego dostosowania nagłówków zobacz przewodnik nagłówków żądań HTTP.

:path=/static-assets/pdf/content-code-examples/how-to/logins-username-password.cs
using IronPdf;
using System;

ChromePdfRenderer renderer = new ChromePdfRenderer
{
    // setting login credentials to bypass basic authentication
    LoginCredentials = new ChromeHttpLoginCredentials()
    {
        NetworkUsername = "testUser",
        NetworkPassword = "testPassword"
    }
};

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

// Render web URL to PDF
PdfDocument pdf = renderer.RenderUrlAsPdf(uri);

// Export PDF
pdf.SaveAs("UrlToPdfExample.Pdf");
Imports IronPdf
Imports System

Private renderer As New ChromePdfRenderer With {
	.LoginCredentials = New ChromeHttpLoginCredentials() With {
		.NetworkUsername = "testUser",
		.NetworkPassword = "testPassword"
	}
}

Private uri = New Uri("http://localhost:51169/Invoice")

' Render web URL to PDF
Private pdf As PdfDocument = renderer.RenderUrlAsPdf(uri)

' Export PDF
pdf.SaveAs("UrlToPdfExample.Pdf")
$vbLabelText   $csharpLabel

Dłączego uwierzytelnienie sieciowe jest bardziej niezawodne niż wysyłanie formularza?

Uwierzytelnienie sieciowe oferuje kilka korzyści w porównaniu do wysyłania formularza HTML:

  1. Ustandaryzowany protokół: Używa nagłówków uwierzytelniania HTTP zgodnie ze standardami RFC
  2. Integracja z przeglądarką: Silnik renderujący Chrome obsługuje uwierzytelnianie bezproblemowo
  3. Zarządzanie sesjami: Automatyczne obsługiwanie wyzwań uwierzytelniania i utrzymywanie sesji
  4. Bezpieczeństwo: Poświadczenia przesyłane bezpiecznie za pomocą nagłówków zamiast danych formularza
  5. Kompatybilność: Współpracuje z większością systemów uwierzytelniania Enterprise (Active Directory, LDAP)

Jakie dane uwierzytelniające są potrzebne do uwierzytelnienia sieciowego?

Różne typy uwierzytelnienia wymagają różnych danych uwierzytelniających:

// Basic Authentication (most common)
var basicAuth = new ChromeHttpLoginCredentials
{
    NetworkUsername = "user@domain.com",
    NetworkPassword = "password123",
    AuthenticationType = ChromeHttpLoginCredentials.AuthType.Basic
};

// NTLM/Windows Authentication
var ntlmAuth = new ChromeHttpLoginCredentials
{
    NetworkUsername = "DOMAIN\\username", // Include domain
    NetworkPassword = "password123",
    AuthenticationType = ChromeHttpLoginCredentials.AuthType.Ntlm
};

// Custom authentication headers
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CustomHttpHeaders.Add("X-API-Key", "your-api-key");
renderer.RenderingOptions.CustomHttpHeaders.Add("Authorization", "Bearer " + jwtToken);
// Basic Authentication (most common)
var basicAuth = new ChromeHttpLoginCredentials
{
    NetworkUsername = "user@domain.com",
    NetworkPassword = "password123",
    AuthenticationType = ChromeHttpLoginCredentials.AuthType.Basic
};

// NTLM/Windows Authentication
var ntlmAuth = new ChromeHttpLoginCredentials
{
    NetworkUsername = "DOMAIN\\username", // Include domain
    NetworkPassword = "password123",
    AuthenticationType = ChromeHttpLoginCredentials.AuthType.Ntlm
};

// Custom authentication headers
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CustomHttpHeaders.Add("X-API-Key", "your-api-key");
renderer.RenderingOptions.CustomHttpHeaders.Add("Authorization", "Bearer " + jwtToken);
Imports System.Collections.Generic

' Basic Authentication (most common)
Dim basicAuth As New ChromeHttpLoginCredentials With {
    .NetworkUsername = "user@domain.com",
    .NetworkPassword = "password123",
    .AuthenticationType = ChromeHttpLoginCredentials.AuthType.Basic
}

' NTLM/Windows Authentication
Dim ntlmAuth As New ChromeHttpLoginCredentials With {
    .NetworkUsername = "DOMAIN\username", ' Include domain
    .NetworkPassword = "password123",
    .AuthenticationType = ChromeHttpLoginCredentials.AuthType.Ntlm
}

' Custom authentication headers
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CustomHttpHeaders.Add("X-API-Key", "your-api-key")
renderer.RenderingOptions.CustomHttpHeaders.Add("Authorization", "Bearer " & jwtToken)
$vbLabelText   $csharpLabel

Jak rozwiązywać problemy z błędami uwierzytelnienia?

Typowe problemy z uwierzytelnieniem i rozwiązania:

  1. 401 Unauthorized: Sprawdź poświadczenia i typ uwierzytelniania
  2. 403 Forbidden: Użytkownik jest uwierzytelniony, ale nie ma uprawnień
  3. Błędy przekroczenia limitu czasu: Zwiększ Timeout dla wolnych systemów uwierzytelniania
  4. Błędy certyfikatów: Skonfiguruj ustawienia TLS/SSL odpowiednio

Włącz debugowanie, aby zdiagnozować problemy:

// Enable detailed logging
IronPdf.Logging.Logger.EnableDebugging = true;
IronPdf.Logging.Logger.LogFilePath = "IronPdf.log";
IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All;

// Test authentication
try 
{
    var pdf = renderer.RenderUrlAsPdf("https://secure.example.com");
    pdf.SaveAs("authenticated.pdf");
}
catch (Exception ex)
{
    Console.WriteLine($"Authentication failed: {ex.Message}");
    // Check IronPdf.log for detailed error information
}
// Enable detailed logging
IronPdf.Logging.Logger.EnableDebugging = true;
IronPdf.Logging.Logger.LogFilePath = "IronPdf.log";
IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All;

// Test authentication
try 
{
    var pdf = renderer.RenderUrlAsPdf("https://secure.example.com");
    pdf.SaveAs("authenticated.pdf");
}
catch (Exception ex)
{
    Console.WriteLine($"Authentication failed: {ex.Message}");
    // Check IronPdf.log for detailed error information
}
Imports IronPdf
Imports System

' Enable detailed logging
Logging.Logger.EnableDebugging = True
Logging.Logger.LogFilePath = "IronPdf.log"
Logging.Logger.LoggingMode = Logging.Logger.LoggingModes.All

' Test authentication
Try
    Dim pdf = renderer.RenderUrlAsPdf("https://secure.example.com")
    pdf.SaveAs("authenticated.pdf")
Catch ex As Exception
    Console.WriteLine($"Authentication failed: {ex.Message}")
    ' Check IronPdf.log for detailed error information
End Try
$vbLabelText   $csharpLabel

Jak zalogować się używając formularza HTML?

Aby zalogować się, przesyłając dane do formularza HTML, użyj klasy ChromeHttpLoginCredentials. Zobacz ChromeHttpLoginCredentials API IronPDF.

Rozważ te punkty:

  • Prześlij dane logowania do URL wskazanego w atrybucie ACTION formularza HTML. Ustaw to jako atrybut LoginFormUrl elementu HttpLoginCredentials. To może się różnić od URL, który chcesz wyrenderować jako PDF.
  • Wyślij dane reprezentujące każdy input i textarea w formularzu HTML. Atrybuty name definiują każdą zmienną (nie id).
  • Niektóre strony aktywnie chronią przed logowaniem maszynowym.
// Configure form-based login
var formLogin = new ChromeHttpLoginCredentials
{
    LoginFormUrl = "https://example.com/login",
    LoginFormData = new Dictionary<string, string>
    {
        {"username", "user@example.com"},
        {"password", "securePassword123"},
        {"rememberMe", "true"},
        {"csrf_token", "abc123"} // Include any hidden fields
    }
};

var renderer = new ChromePdfRenderer
{
    LoginCredentials = formLogin,
    RenderingOptions = new ChromePdfRenderOptions
    {
        RenderDelay = 3000, // Allow time for login redirect
        EnableJavaScript = true
    }
};

// The actual page you want to convert (after login)
var pdf = renderer.RenderUrlAsPdf("https://example.com/dashboard");
pdf.SaveAs("dashboard.pdf");
// Configure form-based login
var formLogin = new ChromeHttpLoginCredentials
{
    LoginFormUrl = "https://example.com/login",
    LoginFormData = new Dictionary<string, string>
    {
        {"username", "user@example.com"},
        {"password", "securePassword123"},
        {"rememberMe", "true"},
        {"csrf_token", "abc123"} // Include any hidden fields
    }
};

var renderer = new ChromePdfRenderer
{
    LoginCredentials = formLogin,
    RenderingOptions = new ChromePdfRenderOptions
    {
        RenderDelay = 3000, // Allow time for login redirect
        EnableJavaScript = true
    }
};

// The actual page you want to convert (after login)
var pdf = renderer.RenderUrlAsPdf("https://example.com/dashboard");
pdf.SaveAs("dashboard.pdf");
Imports System.Collections.Generic

' Configure form-based login
Dim formLogin As New ChromeHttpLoginCredentials With {
    .LoginFormUrl = "https://example.com/login",
    .LoginFormData = New Dictionary(Of String, String) From {
        {"username", "user@example.com"},
        {"password", "securePassword123"},
        {"rememberMe", "true"},
        {"csrf_token", "abc123"} ' Include any hidden fields
    }
}

Dim renderer As New ChromePdfRenderer With {
    .LoginCredentials = formLogin,
    .RenderingOptions = New ChromePdfRenderOptions With {
        .RenderDelay = 3000, ' Allow time for login redirect
        .EnableJavaScript = True
    }
}

' The actual page you want to convert (after login)
Dim pdf = renderer.RenderUrlAsPdf("https://example.com/dashboard")
pdf.SaveAs("dashboard.pdf")
$vbLabelText   $csharpLabel

Jakie dane formularza muszę pobrać?

Aby skutecznie przeprowadzić uwierzytelnienie przez formularze HTML, pobierz wszystkie wejścia formularza:

// Use this helper method to extract form fields
public Dictionary<string, string> ExtractFormFields(string loginPageHtml)
{
    var formData = new Dictionary<string, string>();
    var doc = new HtmlDocument();
    doc.LoadHtml(loginPageHtml);

    // Find all input fields
    var inputs = doc.DocumentNode.SelectNodes("//input");
    if (inputs != null)
    {
        foreach (var input in inputs)
        {
            string name = input.GetAttributeValue("name", "");
            string value = input.GetAttributeValue("value", "");
            string type = input.GetAttributeValue("type", "text");

            if (!string.IsNullOrEmpty(name))
            {
                // Handle different input types
                switch (type.ToLower())
                {
                    case "checkbox":
                        if (input.Attributes["checked"] != null)
                            formData[name] = "on";
                        break;
                    case "radio":
                        if (input.Attributes["checked"] != null)
                            formData[name] = value;
                        break;
                    default:
                        formData[name] = value;
                        break;
                }
            }
        }
    }

    // Don't forget select elements
    var selects = doc.DocumentNode.SelectNodes("//select");
    if (selects != null)
    {
        foreach (var select in selects)
        {
            string name = select.GetAttributeValue("name", "");
            var selected = select.SelectSingleNode(".//option[@selected]");
            if (selected != null && !string.IsNullOrEmpty(name))
            {
                formData[name] = selected.GetAttributeValue("value", "");
            }
        }
    }

    return formData;
}
// Use this helper method to extract form fields
public Dictionary<string, string> ExtractFormFields(string loginPageHtml)
{
    var formData = new Dictionary<string, string>();
    var doc = new HtmlDocument();
    doc.LoadHtml(loginPageHtml);

    // Find all input fields
    var inputs = doc.DocumentNode.SelectNodes("//input");
    if (inputs != null)
    {
        foreach (var input in inputs)
        {
            string name = input.GetAttributeValue("name", "");
            string value = input.GetAttributeValue("value", "");
            string type = input.GetAttributeValue("type", "text");

            if (!string.IsNullOrEmpty(name))
            {
                // Handle different input types
                switch (type.ToLower())
                {
                    case "checkbox":
                        if (input.Attributes["checked"] != null)
                            formData[name] = "on";
                        break;
                    case "radio":
                        if (input.Attributes["checked"] != null)
                            formData[name] = value;
                        break;
                    default:
                        formData[name] = value;
                        break;
                }
            }
        }
    }

    // Don't forget select elements
    var selects = doc.DocumentNode.SelectNodes("//select");
    if (selects != null)
    {
        foreach (var select in selects)
        {
            string name = select.GetAttributeValue("name", "");
            var selected = select.SelectSingleNode(".//option[@selected]");
            if (selected != null && !string.IsNullOrEmpty(name))
            {
                formData[name] = selected.GetAttributeValue("value", "");
            }
        }
    }

    return formData;
}
Imports HtmlAgilityPack

Public Function ExtractFormFields(loginPageHtml As String) As Dictionary(Of String, String)
    Dim formData As New Dictionary(Of String, String)()
    Dim doc As New HtmlDocument()
    doc.LoadHtml(loginPageHtml)

    ' Find all input fields
    Dim inputs = doc.DocumentNode.SelectNodes("//input")
    If inputs IsNot Nothing Then
        For Each input In inputs
            Dim name As String = input.GetAttributeValue("name", "")
            Dim value As String = input.GetAttributeValue("value", "")
            Dim type As String = input.GetAttributeValue("type", "text")

            If Not String.IsNullOrEmpty(name) Then
                ' Handle different input types
                Select Case type.ToLower()
                    Case "checkbox"
                        If input.Attributes("checked") IsNot Nothing Then
                            formData(name) = "on"
                        End If
                    Case "radio"
                        If input.Attributes("checked") IsNot Nothing Then
                            formData(name) = value
                        End If
                    Case Else
                        formData(name) = value
                End Select
            End If
        Next
    End If

    ' Don't forget select elements
    Dim selects = doc.DocumentNode.SelectNodes("//select")
    If selects IsNot Nothing Then
        For Each selectNode In selects
            Dim name As String = selectNode.GetAttributeValue("name", "")
            Dim selected = selectNode.SelectSingleNode(".//option[@selected]")
            If selected IsNot Nothing AndAlso Not String.IsNullOrEmpty(name) Then
                formData(name) = selected.GetAttributeValue("value", "")
            End If
        Next
    End If

    Return formData
End Function
$vbLabelText   $csharpLabel

Jak znaleźć poprawny URL akcji formularza?

URL akcji formularza jest kluczowy dla pomyślnego uwierzytelnienia:

public string ExtractFormAction(string loginPageUrl, string loginPageHtml)
{
    var doc = new HtmlDocument();
    doc.LoadHtml(loginPageHtml);

    // Find the login form
    var form = doc.DocumentNode.SelectSingleNode("//form[contains(@action, 'login') or contains(@id, 'login') or contains(@class, 'login')]");

    if (form == null)
    {
        // Try finding any form with password field
        form = doc.DocumentNode.SelectSingleNode("//form[.//input[@type='password']]");
    }

    if (form != null)
    {
        string action = form.GetAttributeValue("action", "");

        // Resolve relative URLs
        if (!string.IsNullOrEmpty(action))
        {
            var baseUri = new Uri(loginPageUrl);
            var actionUri = new Uri(baseUri, action);
            return actionUri.ToString();
        }
    }

    // Default to the login page URL if no action found
    return loginPageUrl;
}
public string ExtractFormAction(string loginPageUrl, string loginPageHtml)
{
    var doc = new HtmlDocument();
    doc.LoadHtml(loginPageHtml);

    // Find the login form
    var form = doc.DocumentNode.SelectSingleNode("//form[contains(@action, 'login') or contains(@id, 'login') or contains(@class, 'login')]");

    if (form == null)
    {
        // Try finding any form with password field
        form = doc.DocumentNode.SelectSingleNode("//form[.//input[@type='password']]");
    }

    if (form != null)
    {
        string action = form.GetAttributeValue("action", "");

        // Resolve relative URLs
        if (!string.IsNullOrEmpty(action))
        {
            var baseUri = new Uri(loginPageUrl);
            var actionUri = new Uri(baseUri, action);
            return actionUri.ToString();
        }
    }

    // Default to the login page URL if no action found
    return loginPageUrl;
}
Imports System

Public Function ExtractFormAction(loginPageUrl As String, loginPageHtml As String) As String
    Dim doc As New HtmlDocument()
    doc.LoadHtml(loginPageHtml)

    ' Find the login form
    Dim form = doc.DocumentNode.SelectSingleNode("//form[contains(@action, 'login') or contains(@id, 'login') or contains(@class, 'login')]")

    If form Is Nothing Then
        ' Try finding any form with password field
        form = doc.DocumentNode.SelectSingleNode("//form[.//input[@type='password']]")
    End If

    If form IsNot Nothing Then
        Dim action As String = form.GetAttributeValue("action", "")

        ' Resolve relative URLs
        If Not String.IsNullOrEmpty(action) Then
            Dim baseUri As New Uri(loginPageUrl)
            Dim actionUri As New Uri(baseUri, action)
            Return actionUri.ToString()
        End If
    End If

    ' Default to the login page URL if no action found
    Return loginPageUrl
End Function
$vbLabelText   $csharpLabel

Jakie są typowe problemy z uwierzytelnianiem opartym na formularzach?

  1. Tokeny CSRF: Wiele formularzy zawiera tokeny przeciwko fałszowaniu, które wygasają
  2. Walidacja JavaScript: Niektóre formularze wymagają wykonania JavaScript
  3. Uwierzytelnianie wieloetapowe: Formularze wymagające wielu stron
  4. Ochrona CAPTCHA: Wyzwania weryfikacji ludzkiej
  5. Wygasanie sesji: Sesje logowania wygasające szybko

ViewBag TempData Html

Dla kompleksowych wskazówek dotyczących konwersji HTML na PDF, w tym złożonych scenariuszy uwierzytelniania, odwiedź poradnik HTML na PDF.

Jak obsługiwać uwierzytelnienie MVC?

Poniższe obejście renderuje widok .NET MVC do ciągu programatycznie, unikając logowań MVC przy wiernym renderowaniu widoków. To podejście działa dobrze przy konwersji CSHTML do PDF w MVC Core lub MVC Framework.

// Converts an MVC partial view to a string
public static string RenderPartialViewToString(this Controller controller, string viewPath, object model = null)
{
    try
    {
        // Set the model
        var context = controller.ControllerContext;
        controller.ViewData.Model = model;

        using (var sw = new StringWriter())
        {
            // Find the partial view
            var viewResult = ViewEngines.Engines.FindPartialView(context, viewPath);

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

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

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

            return sw.GetStringBuilder().ToString();
        }
    }
    catch (Exception ex)
    {
        // Return error message if there is an exception
        return ex.Message;
    }
}

// Usage in an MVC Controller
public ActionResult GeneratePdf()
{
    // Render authenticated view to string
    var model = new InvoiceViewModel { /* populate model */ };
    string html = this.RenderPartialViewToString("~/Views/Invoice/Details.cshtml", model);

    // Convert to PDF
    var renderer = new ChromePdfRenderer();
    var pdf = renderer.RenderHtmlAsPdf(html);

    // Return PDF file
    return File(pdf.BinaryData, "application/pdf", "invoice.pdf");
}
// Converts an MVC partial view to a string
public static string RenderPartialViewToString(this Controller controller, string viewPath, object model = null)
{
    try
    {
        // Set the model
        var context = controller.ControllerContext;
        controller.ViewData.Model = model;

        using (var sw = new StringWriter())
        {
            // Find the partial view
            var viewResult = ViewEngines.Engines.FindPartialView(context, viewPath);

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

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

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

            return sw.GetStringBuilder().ToString();
        }
    }
    catch (Exception ex)
    {
        // Return error message if there is an exception
        return ex.Message;
    }
}

// Usage in an MVC Controller
public ActionResult GeneratePdf()
{
    // Render authenticated view to string
    var model = new InvoiceViewModel { /* populate model */ };
    string html = this.RenderPartialViewToString("~/Views/Invoice/Details.cshtml", model);

    // Convert to PDF
    var renderer = new ChromePdfRenderer();
    var pdf = renderer.RenderHtmlAsPdf(html);

    // Return PDF file
    return File(pdf.BinaryData, "application/pdf", "invoice.pdf");
}
Imports System
Imports System.IO
Imports System.Web.Mvc
Imports IronPdf

' Converts an MVC partial view to a string
Public Module ControllerExtensions
    <System.Runtime.CompilerServices.Extension>
    Public Function RenderPartialViewToString(controller As Controller, viewPath As String, Optional model As Object = Nothing) As String
        Try
            ' Set the model
            Dim context = controller.ControllerContext
            controller.ViewData.Model = model

            Using sw As New StringWriter()
                ' Find the partial view
                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

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

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

                Return sw.GetStringBuilder().ToString()
            End Using
        Catch ex As Exception
            ' Return error message if there is an exception
            Return ex.Message
        End Try
    End Function
End Module

' Usage in an MVC Controller
Public Class InvoiceController
    Inherits Controller

    Public Function GeneratePdf() As ActionResult
        ' Render authenticated view to string
        Dim model As New InvoiceViewModel() ' populate model
        Dim html As String = Me.RenderPartialViewToString("~/Views/Invoice/Details.cshtml", model)

        ' Convert to PDF
        Dim renderer As New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlAsPdf(html)

        ' Return PDF file
        Return File(pdf.BinaryData, "application/pdf", "invoice.pdf")
    End Function
End Class
$vbLabelText   $csharpLabel

Dłączego renderować widoki do ciągu zamiast bezpośrednio konwertować?

Renderowanie widoków MVC do ciągu oferuje kilka kluczowych korzyści:

  1. Kontekst uwierzytelniania: Widoki są renderowane w kontekście uwierzytelnionego użytkownika
  2. Pełny potok MVC: Działają wszystkie funkcje MVC, w tym pomocniki HtmlHelper, UrlHelper i ViewBag
  3. Obsługa układu: Strony główne i układy są poprawnie wyświetlane
  4. Wiązanie modelu: Złożone modele widoków działają bez problemu
  5. Filtry akcji: Filtry bezpieczeństwa i logowania działają normalnie

Jakie są zalety tego obejścia MVC?

Podejście MVC polegające na renderowaniu ciągu oferuje:

  • Bezpieczeństwo: Bez potrzeby ujawniania wewnętrznych adresów URL lub omijania uwierzytelniania
  • Wydajność: Unikaj dodatkowych żądań HTTP
  • Konsekwencja: Identyczne wyjście do tego, co użytkownicy widzą w przeglądarkach
  • Elastyczność: Modyfikuj HTML przed konwersją PDF
  • Testowanie: Łatwe testowanie jednostkowe generacji HTML

Jak przekazywać modele do wyrenderowanego widoku?

Oto kompletny przykład złożonego modelu:

public class InvoiceController : Controller
{
    private readonly IInvoiceService _invoiceService;

    public async Task<ActionResult> DownloadInvoicePdf(int invoiceId)
    {
        // Load data within authenticated context
        var invoice = await _invoiceService.GetInvoiceAsync(invoiceId);

        if (invoice == null || invoice.UserId != User.Identity.GetUserId())
        {
            return HttpNotFound();
        }

        // Create view model
        var viewModel = new InvoiceDetailsViewModel
        {
            Invoice = invoice,
            Company = await _invoiceService.GetCompanyDetailsAsync(),
            LineItems = await _invoiceService.GetLineItemsAsync(invoiceId),
            TaxDetails = await _invoiceService.GetTaxDetailsAsync(invoiceId)
        };

        // Render to HTML string
        string html = this.RenderPartialViewToString("~/Views/Invoice/DetailsPdf.cshtml", viewModel);

        // Add custom styling for PDF
        html = $@"
            <html>
            <head>
                <style>
                    body {{ font-family: Arial, sans-serif; }}
                    .invoice-header {{ background-color: #f0f0f0; padding: 20px; }}
                    .line-items {{ width: 100%; border-collapse: collapse; }}
                    .line-items th, .line-items td {{ border: 1px solid #ddd; padding: 8px; }}
                </style>
            </head>
            <body>
                {html}
            </body>
            </html>";

        // Convert to PDF with options
        var renderer = new ChromePdfRenderer
        {
            RenderingOptions = new ChromePdfRenderOptions
            {
                MarginTop = 20,
                MarginBottom = 20,
                MarginLeft = 10,
                MarginRight = 10,
                PrintHtmlBackgrounds = true
            }
        };

        var pdf = renderer.RenderHtmlAsPdf(html);

        // Add metadata
        pdf.MetaData.Author = "Invoice System";
        pdf.MetaData.Title = $"Invoice #{invoice.Number}";
        pdf.MetaData.CreationDate = DateTime.Now;

        return File(pdf.BinaryData, "application/pdf", $"Invoice-{invoice.Number}.pdf");
    }
}
public class InvoiceController : Controller
{
    private readonly IInvoiceService _invoiceService;

    public async Task<ActionResult> DownloadInvoicePdf(int invoiceId)
    {
        // Load data within authenticated context
        var invoice = await _invoiceService.GetInvoiceAsync(invoiceId);

        if (invoice == null || invoice.UserId != User.Identity.GetUserId())
        {
            return HttpNotFound();
        }

        // Create view model
        var viewModel = new InvoiceDetailsViewModel
        {
            Invoice = invoice,
            Company = await _invoiceService.GetCompanyDetailsAsync(),
            LineItems = await _invoiceService.GetLineItemsAsync(invoiceId),
            TaxDetails = await _invoiceService.GetTaxDetailsAsync(invoiceId)
        };

        // Render to HTML string
        string html = this.RenderPartialViewToString("~/Views/Invoice/DetailsPdf.cshtml", viewModel);

        // Add custom styling for PDF
        html = $@"
            <html>
            <head>
                <style>
                    body {{ font-family: Arial, sans-serif; }}
                    .invoice-header {{ background-color: #f0f0f0; padding: 20px; }}
                    .line-items {{ width: 100%; border-collapse: collapse; }}
                    .line-items th, .line-items td {{ border: 1px solid #ddd; padding: 8px; }}
                </style>
            </head>
            <body>
                {html}
            </body>
            </html>";

        // Convert to PDF with options
        var renderer = new ChromePdfRenderer
        {
            RenderingOptions = new ChromePdfRenderOptions
            {
                MarginTop = 20,
                MarginBottom = 20,
                MarginLeft = 10,
                MarginRight = 10,
                PrintHtmlBackgrounds = true
            }
        };

        var pdf = renderer.RenderHtmlAsPdf(html);

        // Add metadata
        pdf.MetaData.Author = "Invoice System";
        pdf.MetaData.Title = $"Invoice #{invoice.Number}";
        pdf.MetaData.CreationDate = DateTime.Now;

        return File(pdf.BinaryData, "application/pdf", $"Invoice-{invoice.Number}.pdf");
    }
}
Imports System.Threading.Tasks
Imports System.Web.Mvc

Public Class InvoiceController
    Inherits Controller

    Private ReadOnly _invoiceService As IInvoiceService

    Public Async Function DownloadInvoicePdf(invoiceId As Integer) As Task(Of ActionResult)
        ' Load data within authenticated context
        Dim invoice = Await _invoiceService.GetInvoiceAsync(invoiceId)

        If invoice Is Nothing OrElse invoice.UserId <> User.Identity.GetUserId() Then
            Return HttpNotFound()
        End If

        ' Create view model
        Dim viewModel As New InvoiceDetailsViewModel With {
            .Invoice = invoice,
            .Company = Await _invoiceService.GetCompanyDetailsAsync(),
            .LineItems = Await _invoiceService.GetLineItemsAsync(invoiceId),
            .TaxDetails = Await _invoiceService.GetTaxDetailsAsync(invoiceId)
        }

        ' Render to HTML string
        Dim html As String = Me.RenderPartialViewToString("~/Views/Invoice/DetailsPdf.cshtml", viewModel)

        ' Add custom styling for PDF
        html = $"
            <html>
            <head>
                <style>
                    body {{ font-family: Arial, sans-serif; }}
                    .invoice-header {{ background-color: #f0f0f0; padding: 20px; }}
                    .line-items {{ width: 100%; border-collapse: collapse; }}
                    .line-items th, .line-items td {{ border: 1px solid #ddd; padding: 8px; }}
                </style>
            </head>
            <body>
                {html}
            </body>
            </html>"

        ' Convert to PDF with options
        Dim renderer As New ChromePdfRenderer With {
            .RenderingOptions = New ChromePdfRenderOptions With {
                .MarginTop = 20,
                .MarginBottom = 20,
                .MarginLeft = 10,
                .MarginRight = 10,
                .PrintHtmlBackgrounds = True
            }
        }

        Dim pdf = renderer.RenderHtmlAsPdf(html)

        ' Add metadata
        pdf.MetaData.Author = "Invoice System"
        pdf.MetaData.Title = $"Invoice #{invoice.Number}"
        pdf.MetaData.CreationDate = DateTime.Now

        Return File(pdf.BinaryData, "application/pdf", $"Invoice-{invoice.Number}.pdf")
    End Function
End Class
$vbLabelText   $csharpLabel

Przed wdrożeniem jakiegokolwiek rozwiązania uwierzytelniania, upewnij się, że poprawnie zainstalowałeś IronPDF i skonfigurowałeś swoje klucze licencyjne.

Gotowy, aby sprawdzić, co jeszcze możesz zrobić? Odwiedź naszą stronę z poradnikami: Konwertuj PDF-y. RenderDelay

Często Zadawane Pytania

Jak moge przeksztalcic HTML na PDF, gdy tresc jest za formularzem logowania?

IronPDF udostepnia wiele podejsc do konwersji HTML na PDF za uwierzytelnianiem logowania. Mozesz uzyc ChromeHttpLoginCredentials API do uwierzytelniania sieci TLS, lub pobrac tresc HTML uzywajac System.Net.WebClient lub HttpClient z odpowiednimi naglowkami uwierzytelniajacymi przed przeksztalceniem jej na PDF z IronPDF.

Czym jest ChromeHttpLoginCredentials i jak to uzyc?

ChromeHttpLoginCredentials to API IronPDF do obslugi uwierzytelniania sieciowego. Mozesz z niego korzystac, ustawiajac wlasciwosc LoginCredentials na ChromePdfRenderer z twoja nazwa uzytkownika i haslem, co pozwoli IronPDF na automatyczne uwierzytelnienie podczas renderowania URL zabezpieczonych haslem na PDF.

Czy moge obsługiwać logowania oparte na formularzach HTML do konwersji PDF?

Tak, IronPDF wspiera logowania oparte na formularzach HTML. Zalecanym podejsciem jest uzycie System.Net.WebClient lub HttpClient do obslugi procesu logowania, pobranie uwierzytelnionej tresci HTML, a nastepnie uzycie metody RenderHtmlAsPdf IronPDF do konwersji pobranego HTML na PDF.

Jak moge pobrac zasoby HTML takie jak obrazy i arkusze stylow z uwierzytelnionych stron?

Mozesz uzyc HtmlAgilityPack do parsowania pobranej HTML i wyodrebniania URL zasobow, takich jak obrazy i arkusze stylow. Nastepnie uzyj System.Net.WebClient do pobrania kazdego zasobu z tymi samymi naglowkami uwierzytelniajacymi przed przeksztalceniem kompletnego pakietu HTML na PDF z IronPDF.

Jakie sa najlepsze praktyki dla obslugi tokenow lub naglowkow uwierzytelniajacych?

Kiedy uzywasz IronPDF z tokenami uwierzytelniajacymi, pobierz HTML uzywajac HttpClient lub WebClient z twoimi naglowkami uwierzytelniajacymi (takimi jak tokeny Bearer). Gdy juz bedziesz miec uwierzytelniona tresc HTML w pamieci lub zapisane na dysku, uzyj ChromePdfRenderer IronPDF, aby konwertowac ja na PDF.

Czy istnieje obejscie dla uwierzytelniania logowania MVC?

Tak, IronPDF oferuje obejscia dla scenariuszy uwierzytelniania logowania MVC. Zalecanym podejsciem jest najpierw uwierzytelnienie i pobranie tresci HTML uzywajac standardowych klientow HTTP .NET, a nastepnie przekazanie uwierzytelnionej HTML bezposrednio do silnika renderujacego IronPDF zamiast zlecania uwierzytelniania IronPDF.

Curtis Chau
Autor tekstów technicznych

Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podrę...

Czytaj więcej
Gotowy, aby rozpocząć?
Nuget Pliki do pobrania 18,926,724 | Wersja: 2026.5 just released
Still Scrolling Icon

Wciąż przewijasz?

Czy chcesz szybko dowodu? PM > Install-Package IronPdf
Uruchom przykład i zobacz, jak Twój kod HTML zamienia się w plik PDF.