IronPDF 操作指南 TLS 網站和系統登入 在 C# 中,透過登入驗證將 HTML 轉換為 PDF Curtis Chau 更新:2026年1月10日 下載 IronPDF NuGet 下載 DLL 下載 Windows 安裝程式 開始免費試用 LLM副本 LLM副本 將頁面複製為 Markdown 格式,用於 LLMs 在 ChatGPT 中打開 請向 ChatGPT 諮詢此頁面 在雙子座打開 請向 Gemini 詢問此頁面 在 Grok 中打開 向 Grok 詢問此頁面 打開困惑 向 Perplexity 詢問有關此頁面的信息 分享 在 Facebook 上分享 分享到 X(Twitter) 在 LinkedIn 上分享 複製連結 電子郵件文章 This article was translated from English: Does it need improvement? Translated View the article in English 若要在 C# 中透過登入驗證,或在轉換前轉換為 PDF,請使用 IronPDF 的 ChromeHttpLoginCredentials 進行網頁驗證,或在轉換前使用 HttpClient 下載 HTML。 這種方法可以有效地處理網頁認證和 HTML 表單登入。 快速入門:使用IronPDF在登入後將 HTML 轉換為 PDF 使用 IronPDF 的 API 將登入表單後面的 HTML 頁面轉換為 PDF。 本指南示範了 ChromeHttpLoginCredentials 的驗證和受保護內容檢索。 透過簡潔的程式碼範例,處理網頁驗證和 HTML 表單登入。 使用NuGet套件管理器安裝https://www.nuget.org/packages/IronPdf PM > Install-Package IronPdf 複製並運行這段程式碼。 new ChromePdfRenderer { LoginCredentials = new ChromeHttpLoginCredentials("username","password") } .RenderUrlAsPdf("https://example.com/protected") .SaveAs("secure.pdf"); 部署到您的生產環境進行測試 今天就在您的專案中開始使用免費試用IronPDF Free 30 Day Trial 最簡工作流程(5個步驟) 下載 C# IronPDF庫 下載 HTML 檔案以避免登入。 使用**`LoginCredentials`**屬性透過網路驗證登入 使用 HTML 表單進行驗證 MVC登入驗證的變通方法 處理登入身分驗證的最佳實踐是什麼? IronPDF支援透過ChromeHttpLoginCredentials API進行 TLS 網路驗證(使用者名稱和密碼)。 有關各種登入場景的全面指導,請參閱TLS 網站和系統登入教學。 建議的方法是使用 System.Net.WebClient 或 HttpClient 下載 HTML 和資源。 此方法支援標頭、登入和其他要求。 下載到記憶體或磁碟後, IronPDF會將 HTML 轉換為 PDF。 使用 HtmlAgilityPack 提取樣式表和圖像等資源,然後使用 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 請注意使用重載的 System.Uri 建構子將相對 URL 重新定位為絕對 URL。 若要重新定義 HTML 文件中的所有相對路徑,請使用 HtmlAgilityPack 將 <base> 標籤新增至標頭。 例子。 有關處理 URL 和資源的更多信息,請參閱"基本 URL 和資源編碼"指南。 為什麼需要先下載HTML內容? 轉換前下載HTML內容有以下幾個優點: 1.完全控制:轉換前可修改 HTML、修復失效連結或註入身份驗證令牌 2.資源管理:下載並快取外部資源,例如映像、CSS 和JavaScript文件 3.身份驗證彈性:可使用任何.NET身份驗證機制,包括 OAuth、JWT 令牌或自訂標頭。 4.效能:快取常用內容以降低伺服器負載 5.調試:檢查正在轉換的確切 HTML 程式碼以排查問題。 對於涉及 cookie 和會話的複雜驗證場景,請參閱Cookie 指南,其中解釋了 PDF 轉換期間的驗證狀態管理。 如何處理圖片和樣式表等資源? 轉換已認證頁面時,外部資源通常也需要相同的認證。 以下是使用 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 哪些工具可以幫助解析HTML? HtmlAgilityPack 是.NET中最受歡迎的 HTML 解析庫,但也有其他替代方案: HtmlAgilityPack :最適合通用的 HTML 解析與操作 AngleSharp :一款現代化的、符合標準的 HTML 解析器,支援 CSS 選擇器 CsQuery :針對熟悉 jQuery 的 C# 開發人員的類似 jQuery 的語法 4.正規表示式:適用於簡單的提取任務(不建議用於複雜的 HTML) 如何使用網路身份驗證登入? 大多數ASP.NET應用程式支援網頁驗證,比 HTML 表單提交更可靠。 IronPDF透過 ChromeHttpLoginCredentials 類別提供基本驗證、摘要驗證和 NTLM 驗證的內建支援。 有關更多標頭自訂訊息,請參閱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 為什麼網路認證比表單提交更可靠? 與HTML表單提交相比,網路身分驗證具有以下幾個優點: 1.標準化協定:使用符合 RFC 標準的 HTTP 驗證標頭 2.瀏覽器整合:Chrome 渲染引擎可無縫處理身份驗證。 3.會話管理:自動處理身份驗證挑戰和會話持久性 4.安全性:憑證透過標頭而非表單資料安全傳輸。 5.相容性:可與大多數企業驗證系統搭配使用(Active Directory, LDAP) 我需要哪些憑證才能進行網路身份驗證? 不同的身份驗證類型需要不同的憑證: // 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 如何排除身份驗證失敗問題? 常見身分驗證問題及解決方案: 401 未授權:檢查憑證和驗證類型 403 禁止存取:使用者已通過身份驗證,但缺少權限 3.逾時錯誤:對於速度較慢的身份驗證系統,請增加 RenderDelay 4.憑證錯誤:請正確設定 TLS/SSL 設定 啟用調試功能以診斷問題: // 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 如何使用HTML表單登入? 若要透過向 HTML 表單傳送資料進行登錄,請使用ChromeHttpLoginCredentials類別。 請參閱 IronPDF 的ChromeHttpLoginCredentials API 。 請考慮以下幾點: 將登入資料傳送至 HTML 表單 ACTION 屬性中指定的 URL。 將此設定為 HttpLoginCredentials 的 LoginFormUrl 屬性。 這可能與您想要渲染成 PDF 的 URL 不同。 傳送代表 HTML 表單中每個輸入框和文字區域的資料。 name 屬性定義了每個變數的名稱(而不是 id)。 有些網站會主動採取措施防止機器登入。 以下是一個完整的基於表單的身份驗證範例: // 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 我需要收集哪些表單資料? 若要透過 HTML 表單成功進行驗證,請擷取所有表單輸入: // 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 如何找到正確的表單操作 URL? 表單操作 URL 對於成功進行身份驗證至關重要: 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 基於表單的身份驗證有哪些常見問題? CSRF 令牌:許多表單都包含防偽令牌,這些令牌會過期。 JavaScript驗證:某些表單需要執行JavaScript。 3.多步驟身份驗證:需要多個頁面的表單 4.驗證碼保護:手動驗證挑戰 5.會話逾時:登入會話快速過期。 我該如何進行反機器人保護? 現代網站都採取了防止自動登入的保護措施: // Strategies for handling anti-bot measures var renderer = new ChromePdfRenderer { RenderingOptions = new ChromePdfRenderOptions { // Mimic real browser behavior ViewPortWidth = 1920, ViewPortHeight = 1080, EnableJavaScript = true, RenderDelay = 5000, // Wait for JavaScript // Set a real user agent CustomHttpHeaders = new Dictionary<string, string> { {"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"} } } }; // For sites with rate limiting, add delays between requests System.Threading.Thread.Sleep(2000); // Strategies for handling anti-bot measures var renderer = new ChromePdfRenderer { RenderingOptions = new ChromePdfRenderOptions { // Mimic real browser behavior ViewPortWidth = 1920, ViewPortHeight = 1080, EnableJavaScript = true, RenderDelay = 5000, // Wait for JavaScript // Set a real user agent CustomHttpHeaders = new Dictionary<string, string> { {"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"} } } }; // For sites with rate limiting, add delays between requests System.Threading.Thread.Sleep(2000); ' Strategies for handling anti-bot measures Dim renderer = New ChromePdfRenderer With { .RenderingOptions = New ChromePdfRenderOptions With { ' Mimic real browser behavior .ViewPortWidth = 1920, .ViewPortHeight = 1080, .EnableJavaScript = True, .RenderDelay = 5000, ' Wait for JavaScript ' Set a real user agent .CustomHttpHeaders = New Dictionary(Of String, String) From { {"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"} } } } ' For sites with rate limiting, add delays between requests System.Threading.Thread.Sleep(2000) $vbLabelText $csharpLabel 有關 HTML 到 PDF 轉換的全面指南,包括複雜的身份驗證場景,請造訪HTML 到 PDF 教學。 如何處理 MVC 驗證? 以下解決方法透過程式設計方式將.NET MVC 視圖渲染為字串,從而避免 MVC 登錄,同時忠實渲染視圖。 在 MVC Core 或MVC Framework中將 CSHTML 轉換為 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"); } // 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 為什麼將視圖渲染為字串而不是直接轉換? 將 MVC 視圖渲染為字串具有以下幾個主要優勢: 1.身份驗證上下文:視圖在已驗證使用者的上下文中呈現 2.完整的 MVC 管道:所有 MVC 功能均可正常運作,包括 TempData 和 Html 輔助函數 3.佈局支援:母版頁和佈局能夠正確渲染。 4.模型綁定:複雜的視圖模型可以無縫協作 5.操作過濾器:安全性和日誌過濾器正常執行 這種 MVC 變通方案有什麼好處? MVC字串渲染方法具有以下優點: -安全性:無需暴露內部 URL 或繞過身份驗證 -效能:避免額外的 HTTP 請求 -一致性:輸出結果與使用者在瀏覽器中看到的結果完全一致 -靈活性:可在轉換為 PDF 之前修改 HTML -測試:輕鬆產生單元測試 HTML 如何將模型傳遞給渲染視圖? 以下是一個包含複雜模型的全面範例: 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 在實施任何身份驗證解決方案之前,請確保已正確安裝IronPDF並配置了許可證金鑰。 準備好要看看你還能做什麼了嗎? 造訪我們的教學頁面:轉換 PDF 。 常見問題解答 當內容位於登入表單之後,我該如何將 HTML 轉換成 PDF? IronPDF 提供了多種在登入驗證後將 HTML 轉換為 PDF 的方法。您可以使用 ChromeHttpLoginCredentials API 進行 TLS 網路驗證,或使用 System.Net.WebClient 或 HttpClient 下載 HTML 內容,並加上適當的驗證標頭,然後再使用 IronPDF 將其轉換為 PDF。 什麼是 ChromeHttpLoginCredentials? ChromeHttpLoginCredentials 是 IronPDF 處理網路認證的 API。您可以通過在 ChromePdfRenderer 上的 LoginCredentials 屬性中設置您的用戶名和密碼來使用它,允許 IronPDF 在將受密碼保護的 URL 渲染成 PDF 時自動進行身份驗證。 我可以處理基於 HTML 表單的登入 PDF 轉換嗎? 是的,IronPDF 支持基于 HTML 表单的登录。建議的方法是使用 System.Net.WebClient 或 HttpClient 來處理登入過程,下載驗證的 HTML 內容,然後再使用 IronPDF 的 RenderHtmlAsPdf 方法將下載的 HTML 轉換成 PDF。 如何從驗證的頁面下載圖片和樣式表等 HTML 資產? 您可以使用 HtmlAgilityPack 來解析下載的 HTML 並擷取資產 URL,例如圖片和樣式表。然後使用 System.Net.WebClient 下載每個具有相同驗證標頭的資產,最後再使用 IronPDF 將完整的 HTML 套件轉換為 PDF。 處理認證標記或標頭的最佳做法是什麼? 使用 IronPDF 時,請使用 HttpClient 或 WebClient 下載 HTML,並附上驗證標頭(例如 Bearer tokens)。一旦您在記憶體或磁碟中儲存了認證的 HTML 內容,請使用 IronPDF 的 ChromePdfRenderer 將其轉換為 PDF。 MVC 登入驗證有變通的方法嗎? 是的,IronPDF 為 MVC 登入驗證情況提供了變通方案。建議的方法是先使用標準的 .NET HTTP 客戶端驗證和下載 HTML 內容,然後將驗證的 HTML 直接傳遞給 IronPDF 的渲染引擎,而不是由 IronPDF 處理驗證。 Curtis Chau 立即與工程團隊聊天 技術作家 Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。 準備好開始了嗎? Nuget 下載 18,120,209 | 版本: 2026.4 剛剛發布 開始免費試用 免費 NuGet 下載 總下載量:18,120,209 查看許可證 還在捲動嗎? 想要快速證明? PM > Install-Package IronPdf 執行範例 觀看您的 HTML 變成 PDF。 免費 NuGet 下載 總下載量:18,120,209 查看許可證