C#을 사용하여 로그인 및 인증을 관리하는 방법

C#에서 로그인 인증 후 HTML을 PDF로 변환

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

C#에서 로그인 인증이 필요한 HTML을 PDF로 변환하려면 IronPDF의 ChromeHttpLoginCredentials를 사용하여 네트워크 인증을 수행하거나 변환 전에 System.Net.WebClient/HttpClient를 사용하여 HTML을 다운로드하십시오. 이 접근 방식은 네트워크 인증과 HTML 폼 로그인 모두를 효과적으로 처리합니다.

빠른 시작: IronPDF를 사용하여 로그인하지 않은 HTML을 PDF로 변환

IronPDF API를 사용하여 로그인 양식 뒤에 있는 HTML 페이지를 PDF로 변환하세요. 이 가이드는 인증 및 보호된 콘텐츠 검색을 위한 ChromeHttpLoginCredentials 사용법을 설명합니다. 간단한 코드 예제를 통해 네트워크 인증과 HTML 폼 로그인 모두를 처리하세요.

Nuget Icon지금 바로 NuGet을 사용하여 PDF 만들기를 시작하세요.

  1. NuGet 패키지 관리자를 사용하여 IronPDF를 설치하세요.

    PM > Install-Package IronPdf

  2. 다음 코드 조각을 복사하여 실행하세요.

    new ChromePdfRenderer { LoginCredentials = new ChromeHttpLoginCredentials("username","password") }
        .RenderUrlAsPdf("https://example.com/protected")
        .SaveAs("secure.pdf");
  3. 실제 운영 환경에서 테스트할 수 있도록 배포하세요.

    지금 바로 무료 체험판을 통해 프로젝트에서 IronPDF를 사용해 보세요.
    arrow pointer


로그인 인증 처리를 위한 최적의 방법은 무엇일까요?

IronPDF는 ChromeHttpLoginCredentials API를 통해 TLS 네트워크 인증(사용자 이름 및 암호)을 지원합니다. 다양한 로그인 시나리오에 대한 자세한 안내는 TLS 웹사이트 및 시스템 로그인 튜토리얼을 참조하세요.

HTML 및 자산을 다운로드하려면 System.Net.WebClient 또는 HttpClient를 사용하는 것이 좋습니다. 이 메서드는 헤더, 로그인 및 기타 요구 사항을 지원합니다. 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");
$vbLabelText   $csharpLabel

[{i:(오버로드된 System.Uri 생성자를 사용하여 상대 URL을 절대 URL로 리베이스합니다. HTML 문서의 모든 상대 경로를 리베이스하려면 HtmlAgilityPack을 사용하여 헤더에 <base> 태그를 추가하세요. . URL 및 자산 처리 방법에 대한 자세한 내용은 기본 URL 및 자산 인코딩 가이드를 참조하세요.

HTML 콘텐츠를 먼저 다운로드해야 하는 이유는 무엇인가요?

변환 전에 HTML 콘텐츠를 다운로드하면 다음과 같은 몇 가지 이점이 있습니다.

  1. 완벽한 제어 : 변환 전에 HTML을 수정하고, 깨진 링크를 고치거나, 인증 토큰을 삽입할 수 있습니다.
  2. 자산 관리 : 이미지, CSS, JavaScript 파일과 같은 외부 리소스를 다운로드하고 캐시합니다.
  3. 인증 유연성 : OAuth, JWT 토큰 또는 사용자 지정 헤더를 포함한 모든 .NET 인증 메커니즘을 사용할 수 있습니다.
  4. 성능 : 자주 액세스하는 콘텐츠를 캐시하여 서버 부하를 줄입니다.
  5. 디버깅 : 변환되는 HTML을 정확히 검사하여 문제를 해결합니다.

쿠키 및 세션을 사용하는 복잡한 인증 시나리오의 경우, 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;
    }
}
$vbLabelText   $csharpLabel

HTML 파싱에 도움이 되는 도구는 무엇인가요?

HtmlAgilityPack는 .NET에서 가장 인기 있는 HTML 파싱 라이브러리이지만, 다른 대안도 있습니다.

  1. HtmlAgilityPack : 일반적인 HTML 구문 분석 및 조작에 가장 적합합니다.
  2. AngleSharp : CSS 선택자 지원 기능을 갖춘 최신 표준 준수 HTML 파서
  3. 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");
$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);
$vbLabelText   $csharpLabel

인증 실패 문제를 어떻게 해결하나요?

일반적인 인증 문제 및 해결 방법:

  1. 401 권한 없음 : 자격 증명 및 인증 유형을 확인하십시오.
  2. 403 Forbidden : 사용자는 인증되었지만 권한이 부족합니다.
  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
}
$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");
$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;
}
$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;
}
$vbLabelText   $csharpLabel

폼 기반 인증에서 흔히 발생하는 문제점은 무엇인가요?

  1. CSRF 토큰 : 많은 양식에는 만료되는 위조 방지 토큰이 포함되어 있습니다.
  2. 자바스크립트 유효성 검사 : 일부 양식은 자바스크립트 실행을 필요로 합니다.
  3. 다단계 인증 : 여러 페이지를 필요로 하는 양식
  4. CAPTCHA 보호 : 사람 인증 문제
  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);
$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");
}
$vbLabelText   $csharpLabel

뷰를 직접 변환하는 대신 문자열로 렌더링하는 이유는 무엇일까요?

MVC 뷰를 문자열로 렌더링하면 다음과 같은 몇 가지 주요 이점이 있습니다.

  1. 인증 컨텍스트 : 뷰는 인증된 사용자의 컨텍스트 내에서 렌더링됩니다.
  2. 완전한 MVC 파이프라인 : ViewBag, TempData, Html 헬퍼를 포함한 모든 MVC 기능이 작동합니다.
  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");
    }
}
$vbLabelText   $csharpLabel

인증 솔루션을 구현하기 전에 IronPDF가 제대로 설치되었고 라이선스 키가 구성되었는지 확인하십시오.

당신이 할 수 있는 다른 일들을 알아볼 준비가 되셨나요? PDF 변환 방법 튜토리얼 페이지를 방문하세요.

자주 묻는 질문

로그인 양식 뒤에 있는 HTML 콘텐츠를 PDF로 변환하려면 어떻게 해야 하나요?

IronPDF는 로그인 인증을 통해 HTML을 PDF로 변환하는 다양한 방법을 제공합니다. TLS 네트워크 인증을 위해 ChromeHttpLoginCredentials API를 사용하거나, System.Net.WebClient 또는 HttpClient를 사용하여 적절한 인증 헤더와 함께 HTML 콘텐츠를 다운로드한 후 IronPDF로 PDF 변환을 수행할 수 있습니다.

ChromeHttpLoginCredentials는 무엇이며 어떻게 사용하나요?

ChromeHttpLoginCredentials는 IronPDF의 네트워크 인증 처리 API입니다. ChromePdfRenderer의 LoginCredentials 속성에 사용자 이름과 비밀번호를 설정하여 이 API를 사용할 수 있습니다. 이렇게 하면 IronPDF가 비밀번호로 보호된 URL을 PDF로 렌더링할 때 자동으로 인증합니다.

PDF 변환 시 HTML 폼 기반 로그인을 처리할 수 있나요?

예, IronPDF는 HTML 폼 기반 로그인을 지원합니다. 권장되는 방법은 System.Net.WebClient 또는 HttpClient를 사용하여 로그인 프로세스를 처리하고, 인증된 HTML 콘텐츠를 다운로드한 다음, IronPDF의 RenderHtmlAsPdf 메서드를 사용하여 다운로드한 HTML을 PDF로 변환하는 것입니다.

인증된 페이지에서 이미지나 스타일시트 같은 HTML 자산을 어떻게 다운로드할 수 있나요?

다운로드한 HTML을 파싱하고 이미지 및 스타일시트와 같은 자산 URL을 추출하려면 HtmlAgilityPack을 사용할 수 있습니다. 그런 다음 System.Net.WebClient를 사용하여 동일한 인증 헤더로 각 자산을 다운로드하고, 마지막으로 IronPDF를 사용하여 전체 HTML 패키지를 PDF로 변환합니다.

인증 토큰이나 헤더를 처리하는 가장 좋은 방법은 무엇일까요?

IronPDF를 인증 토큰과 함께 사용할 때는 HttpClient 또는 WebClient를 사용하여 인증 헤더(예: Bearer 토큰)와 함께 HTML을 다운로드하세요. 인증된 HTML 콘텐츠를 메모리에 로드하거나 디스크에 저장한 후에는 IronPDF의 ChromePdfRenderer를 사용하여 PDF로 변환하세요.

MVC 로그인 인증에 대한 해결 방법이 있을까요?

네, IronPDF는 MVC 로그인 인증 시나리오에 대한 해결 방법을 제공합니다. 권장되는 방법은 먼저 표준 .NET HTTP 클라이언트를 사용하여 HTML 콘텐츠를 인증하고 다운로드한 다음, 인증된 HTML을 IronPDF의 렌더링 엔진에 직접 전달하는 것입니다. 이렇게 하면 IronPDF에서 인증을 처리하도록 할 필요가 없습니다.

커티스 차우
기술 문서 작성자

커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다.

커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다.

시작할 준비 되셨나요?
Nuget 다운로드 17,527,568 | 버전: 2026.2 방금 출시되었습니다