C# ASP.NET Core MVC에서 뷰의 PDF 변환 방법
IronPDF의 RenderRazorViewToPdf 메소드를 사용하여 ASP.NET Core MVC 뷰를 PDF로 변환합니다. 이 메소드는 .cshtml 파일을 한 줄의 코드로 MVC 애플리케이션 내에서 고품질 PDF 문서로 변환합니다.
뷰는 ASP.NET Framework에서 웹 애플리케이션의 HTML 마크업을 생성하는 데 사용되는 구성 요소입니다. 이는 ASP.NET MVC 및 ASP.NET Core MVC 애플리케이션에서 일반적으로 사용되는 모델-뷰-컨트롤러(MVC) 패턴의 일부입니다. 뷰는 HTML 콘텐츠를 동적으로 렌더링하여 사용자에게 데이터를 표시하는 역할을 합니다. 뷰는 일반적으로 서버 기반 코드를 웹페이지에 삽입하기 위한 마크업 구문인 Razor 구문을 사용하므로 데이터 기반 PDF 문서를 생성하는 데 강력한 도구입니다.
빠른 시작: ASP.NET Core 에서 CSHTML을 PDF로 변환하기
IronPDF 사용하여 ASP.NET Core MVC 뷰를 PDF로 변환합니다. 단 한 줄의 코드로 '.cshtml' 파일을 PDF 문서로 렌더링할 수 있습니다. 이 기능을 MVC 애플리케이션에 직접 통합하여 동적 HTML 뷰에서 PDF를 원활하게 생성할 수 있습니다. 이 가이드를 따라 환경을 설정하고 변환을 시작하세요.
-
NuGet 패키지 관리자를 사용하여 https://www.nuget.org/packages/IronPdf 설치하기
PM > Install-Package IronPdf -
다음 코드 조각을 복사하여 실행하세요.
// using IronPdf.Extensions.Mvc.Core new IronPdf.ChromePdfRenderer().RenderRazorViewToPdf(HttpContext, "Views/Home/Report.cshtml", model).SaveAs("report.pdf"); -
실제 운영 환경에서 테스트할 수 있도록 배포하세요.
무료 체험판으로 오늘 프로젝트에서 IronPDF 사용 시작하기
ASP.NET Core 웹 앱 MVC(모델-뷰-컨트롤러)는 Microsoft에서 ASP.NET Core 사용하여 웹 애플리케이션을 구축하기 위해 제공하는 웹 애플리케이션 프레임워크입니다.
- 모델 : 데이터와 비즈니스 로직을 표현하고, 데이터 상호작용을 관리하며, 데이터 소스와 통신합니다.
- 뷰 : 사용자 인터페이스를 제공하고, 데이터를 표시하며, 사용자에게 정보를 렌더링합니다.
- 컨트롤러 : 사용자 입력을 처리하고, 요청에 응답하며, 모델과 통신하고, 모델-뷰 상호작용을 조율합니다.
IronPDF ASP.NET Core MVC 프로젝트 내의 뷰에서 직접 PDF 파일을 생성할 수 있도록 지원합니다. 이를 통해 ASP.NET Core MVC에서 PDF 생성이 간편해지며 CSS 스타일링 , JavaScript 실행 및 사용자 지정 글꼴을 포함한 최신 기능을 지원합니다.
최소 워크플로우(5단계)
- ASP.NET Core MVC에서 뷰를 PDF로 변환하는 C# 라이브러리를 다운로드하세요.
- 데이터에 대한 모델 클래스를 추가하세요
- "HomeController.cs" 파일을 편집하고 `RenderRazorViewToPdf` 메서드를 사용하세요.
- 새 뷰를 생성하고 ".cshtml" 파일을 편집하여 PDF를 렌더링하십시오.
- 빠른 시작을 위해 샘플 프로젝트를 다운로드하세요.
IronPDF 확장 기능을 사용하려면 어떤 패키지가 필요합니까?
IronPdf.Extensions.Mvc.Core 패키지는 기본 IronPdf 패키지의 확장입니다. ASP.NET Core MVC에서 뷰를 PDF 문서로 렌더링하려면 IronPdf.Extensions.Mvc.Core 및 IronPdf 패키지가 필요합니다. 이 확장 패키지는 ASP.NET Core의 종속성 주입 시스템 및 Razor 뷰 렌더링 파이프라인과의 통합을 위한 특정 기능을 제공합니다.
Install-Package IronPdf.Extensions.Mvc.Core
IronPDF 와 확장 프로그램 패키지가 모두 필요한 이유는 무엇인가요?
IronPDF 메인 패키지에는 핵심 PDF 렌더링 엔진과 기본 기능이 포함되어 있으며, Extensions.Mvc.Core 패키지는 ASP.NET Core MVC의 뷰 렌더링 시스템과의 특수 통합을 제공합니다. 이러한 분리를 통해 모듈성을 향상시키고 프로젝트 유형에 필요한 특정 기능만 포함할 수 있습니다. 확장 패키지에는 PDF 생성을 시작하기 전에 Razor 뷰를 HTML로 변환하는 데 필요한 IRazorViewRenderer 인터페이스와 구현이 포함되어 있습니다.
어떤 NuGet 패키지 버전을 사용해야 할까요?
호환성을 보장하기 위해 항상 IronPDF과 IronPdf.Extensions.Mvc.Core의 일치하는 버전을 사용하세요. 최신 안정 버전 및 버전 호환성 정보는 NuGet 패키지 설명서를 참조하세요. 업데이트 시에는 두 패키지 모두 함께 업데이트해야 정상적인 기능이 유지됩니다.
설치 시 흔히 발생하는 문제는 무엇인가요?
일반적인 설치 문제로는 코어 패키지와 확장 패키지 간의 버전 불일치, 누락된 종속성 또는 플랫폼별 요구 사항 등이 있습니다. 문제가 발생하는 경우 프로젝트가 지원되는 .NET 버전을 대상으로 하는지 확인하고 설치 개요에서 문제 해결 단계를 참조하십시오.
Install-Package IronPdf.Extensions.Mvc.Core
뷰를 PDF로 렌더링하는 방법은 무엇인가요?
뷰를 PDF 파일로 변환하려면 ASP.NET Core 웹 앱(모델-뷰-컨트롤러) 프로젝트가 필요합니다. 이 프로세스는 IronPDF의 RenderRazorViewToPdf 메소드를 사용하여 Razor 뷰를 PDF 문서로 변환하는 컨트롤러 동작을 만드는 것을 포함합니다. 이 접근 방식은 Razor 구문의 모든 기능을 활용하여 동적 콘텐츠를 포함하는 복잡하고 데이터 기반의 PDF를 생성할 수 있도록 합니다.
어떤 프로젝트 유형을 사용해야 할까요?
IronPDF의 뷰 렌더링 기능과의 최적의 호환성을 위해 ASP.NET Core 웹 앱(모델-뷰-컨트롤러) 템플릿을 사용하십시오. 이 프로젝트 유형은 Razor 뷰 엔진 및 적절한 라우팅을 포함하여 뷰 렌더링에 필요한 인프라를 제공합니다. 기존 프로젝트의 경우, MVC 패턴을 준수하고 필요한 뷰 렌더링 기능이 설치되어 있는지 확인하십시오.
최소한의 API로도 사용할 수 있을까요?
Minimal API는 내장된 뷰 지원 기능을 제공하지 않지만, IronPDF의 HTML을 PDF로 변환하는 기능을 사용할 수 있습니다. 뷰 기반 PDF 생성을 위해서는 기존의 MVC 방식을 사용하거나 대안으로 Razor Pages를 고려해 보세요.
모델 클래스를 어떻게 추가하나요?
- "Models" 폴더로 이동하세요.
- "Person"이라는 이름의 새로운 C# 클래스 파일을 생성하세요. 이 클래스는 개인 데이터를 나타내는 모델 역할을 합니다. 다음 코드 조각을 사용하세요.
:path=/static-assets/pdf/content-code-examples/how-to/cshtml-to-pdf-mvc-core-model.cs
namespace ViewToPdfMVCCoreSample.Models
{
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
}
Namespace ViewToPdfMVCCoreSample.Models
Public Class Person
Public Property Id() As Integer
Public Property Name() As String
Public Property Title() As String
Public Property Description() As String
End Class
End Namespace
PDF 생성을 위해 모델이 필요한 이유는 무엇인가요?
모델은 뷰에 전달하여 렌더링할 수 있는 구조화된 데이터를 제공합니다. 이러한 관심사 분리는 PDF 생성 로직을 깔끔하고 유지보수하기 쉽게 유지해 줍니다. 이 모델은 컨트롤러와 뷰 간의 계약 역할을 하여 타입 안정성을 보장하고 Razor 뷰에서 IntelliSense 지원을 활성화합니다.
뷰와 가장 잘 어울리는 데이터 유형은 무엇인가요?
PDF 생성에는 간단한 데이터 유형과 컬렉션이 가장 적합합니다. 복잡하게 중첩된 객체를 사용할 수 있지만 추가적인 뷰 로직이 필요할 수 있습니다. 최적의 성능을 위해서는 복잡한 데이터 구조를 컨트롤러에서 평면화한 후 뷰로 전달하는 것이 좋습니다. 도메인 모델이 너무 복잡한 경우 PDF 출력용으로 특별히 설계된 ViewModel을 사용하는 것을 고려해 보세요.
다음은 PDF 생성에 적합한 보다 복잡한 모델 구조의 예입니다.
public class InvoiceViewModel
{
public string InvoiceNumber { get; set; }
public DateTime InvoiceDate { get; set; }
public decimal TotalAmount { get; set; }
public List<InvoiceLineItem> LineItems { get; set; }
public CustomerInfo Customer { get; set; }
// Computed property for PDF display
public string FormattedTotal => TotalAmount.ToString("C");
}
public class InvoiceLineItem
{
public string Description { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal LineTotal => Quantity * UnitPrice;
}
public class CustomerInfo
{
public string Name { get; set; }
public string Email { get; set; }
public string Address { get; set; }
}
public class InvoiceViewModel
{
public string InvoiceNumber { get; set; }
public DateTime InvoiceDate { get; set; }
public decimal TotalAmount { get; set; }
public List<InvoiceLineItem> LineItems { get; set; }
public CustomerInfo Customer { get; set; }
// Computed property for PDF display
public string FormattedTotal => TotalAmount.ToString("C");
}
public class InvoiceLineItem
{
public string Description { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal LineTotal => Quantity * UnitPrice;
}
public class CustomerInfo
{
public string Name { get; set; }
public string Email { get; set; }
public string Address { get; set; }
}
Public Class InvoiceViewModel
Public Property InvoiceNumber As String
Public Property InvoiceDate As DateTime
Public Property TotalAmount As Decimal
Public Property LineItems As List(Of InvoiceLineItem)
Public Property Customer As CustomerInfo
' Computed property for PDF display
Public ReadOnly Property FormattedTotal As String
Get
Return TotalAmount.ToString("C")
End Get
End Property
End Class
Public Class InvoiceLineItem
Public Property Description As String
Public Property Quantity As Integer
Public Property UnitPrice As Decimal
Public ReadOnly Property LineTotal As Decimal
Get
Return Quantity * UnitPrice
End Get
End Property
End Class
Public Class CustomerInfo
Public Property Name As String
Public Property Email As String
Public Property Address As String
End Class
컨트롤러를 어떻게 편집하나요?
"Controllers" 폴더로 이동하여 "HomeController" 파일을 엽니다. 우리는 HomeController만 변경하고 Persons 동작을 추가할 것입니다. 아래 코드를 참조하여 지침을 따르십시오.
아래 코드에서는 먼저 ChromePdfRenderer 클래스를 인스턴스화하고 IRazorViewRenderer, Views/Home/Persons.cshtml에 대한 경로, 필요한 데이터를 포함하는 목록을 RenderRazorViewToPdf 메소드로 전달합니다. 사용자는 RenderingOptions을 통해 사용자 정의 텍스트 추가, 결과 PDF에 HTML 헤더 및 푸터 포함, 사용자 정의 여백 정의, 페이지 번호 적용 등의 다양한 기능에 접근할 수 있습니다. 보다 고급적인 렌더링 옵션에 대해서는 렌더링 옵션 설명서를 참조하십시오.
{i:(PDF 문서는 다음 코드를 사용하여 브라우저에서 볼 수 있습니다: File(pdf.BinaryData, "application/pdf")}. 하지만 브라우저에서 PDF 파일을 본 후 다운로드하면 PDF 문서가 손상됩니다.
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using ViewToPdfMVCCoreSample.Models;
namespace ViewToPdfMVCCoreSample.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IRazorViewRenderer _viewRenderService;
private readonly IHttpContextAccessor _httpContextAccessor;
public HomeController(ILogger<HomeController> logger, IRazorViewRenderer viewRenderService, IHttpContextAccessor httpContextAccessor)
{
_logger = logger;
_viewRenderService = viewRenderService;
_httpContextAccessor = httpContextAccessor;
}
public IActionResult Index()
{
return View();
}
public async Task<IActionResult> Persons()
{
// Example list of persons
var persons = new List<Person>
{
new Person { Name = "Alice", Title = "Mrs.", Description = "Software Engineer" },
new Person { Name = "Bob", Title = "Mr.", Description = "Software Engineer" },
new Person { Name = "Charlie", Title = "Mr.", Description = "Software Engineer" }
};
// Check if the request method is POST
if (_httpContextAccessor.HttpContext.Request.Method == HttpMethod.Post.Method)
{
// Create a new PDF renderer
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Configure rendering options for better output
renderer.RenderingOptions.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
renderer.RenderingOptions.Title = "Persons Report";
// Render View to PDF document
PdfDocument pdf = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons);
Response.Headers.Add("Content-Disposition", "inline");
// Output PDF document
return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf");
}
return View(persons);
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using ViewToPdfMVCCoreSample.Models;
namespace ViewToPdfMVCCoreSample.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IRazorViewRenderer _viewRenderService;
private readonly IHttpContextAccessor _httpContextAccessor;
public HomeController(ILogger<HomeController> logger, IRazorViewRenderer viewRenderService, IHttpContextAccessor httpContextAccessor)
{
_logger = logger;
_viewRenderService = viewRenderService;
_httpContextAccessor = httpContextAccessor;
}
public IActionResult Index()
{
return View();
}
public async Task<IActionResult> Persons()
{
// Example list of persons
var persons = new List<Person>
{
new Person { Name = "Alice", Title = "Mrs.", Description = "Software Engineer" },
new Person { Name = "Bob", Title = "Mr.", Description = "Software Engineer" },
new Person { Name = "Charlie", Title = "Mr.", Description = "Software Engineer" }
};
// Check if the request method is POST
if (_httpContextAccessor.HttpContext.Request.Method == HttpMethod.Post.Method)
{
// Create a new PDF renderer
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Configure rendering options for better output
renderer.RenderingOptions.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
renderer.RenderingOptions.Title = "Persons Report";
// Render View to PDF document
PdfDocument pdf = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons);
Response.Headers.Add("Content-Disposition", "inline");
// Output PDF document
return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf");
}
return View(persons);
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
Imports IronPdf.Extensions.Mvc.Core
Imports Microsoft.AspNetCore.Mvc
Imports System.Diagnostics
Imports ViewToPdfMVCCoreSample.Models
Namespace ViewToPdfMVCCoreSample.Controllers
Public Class HomeController
Inherits Controller
Private ReadOnly _logger As ILogger(Of HomeController)
Private ReadOnly _viewRenderService As IRazorViewRenderer
Private ReadOnly _httpContextAccessor As IHttpContextAccessor
Public Sub New(logger As ILogger(Of HomeController), viewRenderService As IRazorViewRenderer, httpContextAccessor As IHttpContextAccessor)
_logger = logger
_viewRenderService = viewRenderService
_httpContextAccessor = httpContextAccessor
End Sub
Public Function Index() As IActionResult
Return View()
End Function
Public Async Function Persons() As Task(Of IActionResult)
' Example list of persons
Dim persons = New List(Of Person) From {
New Person With {.Name = "Alice", .Title = "Mrs.", .Description = "Software Engineer"},
New Person With {.Name = "Bob", .Title = "Mr.", .Description = "Software Engineer"},
New Person With {.Name = "Charlie", .Title = "Mr.", .Description = "Software Engineer"}
}
' Check if the request method is POST
If _httpContextAccessor.HttpContext.Request.Method = HttpMethod.Post.Method Then
' Create a new PDF renderer
Dim renderer As New ChromePdfRenderer()
' Configure rendering options for better output
renderer.RenderingOptions.MarginTop = 40
renderer.RenderingOptions.MarginBottom = 40
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait
renderer.RenderingOptions.Title = "Persons Report"
' Render View to PDF document
Dim pdf As PdfDocument = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons)
Response.Headers.Add("Content-Disposition", "inline")
' Output PDF document
Return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf")
End If
Return View(persons)
End Function
Public Function Privacy() As IActionResult
Return View()
End Function
<ResponseCache(Duration:=0, Location:=ResponseCacheLocation.None, NoStore:=True)>
Public Function Error() As IActionResult
Return View(New ErrorViewModel With {.RequestId = If(Activity.Current?.Id, HttpContext.TraceIdentifier)})
End Function
End Class
End Namespace
RenderRazorViewToPdf 메소드를 사용한 후, 잠재적인 개선 및 수정에 열려 있는 PdfDocument 객체를 받습니다. PDF 파일을 PDF/A 또는 PDF/UA 형식으로 변환하거나, 생성된 PDF에 디지털 서명을 추가하거나, 필요에 따라 PDF 문서를 병합 및 분할할 수 있습니다. 또한, 이 라이브러리를 사용하면 페이지를 회전하고, 주석이나 책갈피를 삽입하고, PDF 파일에 고유한 워터마크를 넣을 수 있습니다.
IRazorViewRenderer 서비스란 무엇인가요?
IRazorViewRenderer은 IronPdf.Extensions.Mvc.Core 패키지에서 제공하는 서비스 인터페이스로, Razor 뷰를 HTML로 변환하는 작업을 처리합니다. 이 프로그램은 ASP.NET Core의 뷰 엔진과 통합되어 관련 모델이 포함된 .cshtml 파일을 처리하고, 모든 Razor 구문을 실행하여 IronPDF PDF로 변환하는 최종 HTML을 생성합니다.
렌더링 전에 POST 메서드를 확인하는 이유는 무엇인가요?
POST 요청을 확인하면 양식 제출을 통해 명시적으로 요청된 경우에만 PDF가 생성됩니다. 이렇게 하면 페이지 로드 시 PDF가 실수로 생성되는 것을 방지하고, 동일한 작업을 통해 HTML 보기(GET 요청 시)와 PDF 다운로드(POST 요청 시)를 모두 제공할 수 있습니다. 이 패턴은 RESTful 원칙을 따르며 더 나은 사용자 경험을 제공합니다.
PDF 출력 형식을 어떻게 사용자 지정할 수 있나요?
IronPDF는 RenderingOptions 속성을 통해 광범위한 사용자 정의 옵션을 제공합니다. 다음은 고급 설정이 포함된 예입니다.
// Advanced rendering configuration example
var renderer = new ChromePdfRenderer();
// Page setup
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
// Headers and footers with merge fields
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
Height = 25,
HtmlFragment = "<div style='text-align: center; font-size: 12px;'>Page {page} of {total-pages}</div>"
};
// JavaScript execution delay for dynamic content
renderer.RenderingOptions.WaitFor = new WaitFor()
{
RenderDelay = 500, // Wait 500ms for JS execution
NetworkIdle = NetworkIdleTypes.NetworkIdle0 // Wait for network requests
};
// Apply watermark
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
DrawDividerLine = true,
CenterText = "CONFIDENTIAL",
Font = new FontTypes() { FontSize = 16 }
};
// Advanced rendering configuration example
var renderer = new ChromePdfRenderer();
// Page setup
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
// Headers and footers with merge fields
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
Height = 25,
HtmlFragment = "<div style='text-align: center; font-size: 12px;'>Page {page} of {total-pages}</div>"
};
// JavaScript execution delay for dynamic content
renderer.RenderingOptions.WaitFor = new WaitFor()
{
RenderDelay = 500, // Wait 500ms for JS execution
NetworkIdle = NetworkIdleTypes.NetworkIdle0 // Wait for network requests
};
// Apply watermark
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
DrawDividerLine = true,
CenterText = "CONFIDENTIAL",
Font = new FontTypes() { FontSize = 16 }
};
' Advanced rendering configuration example
Dim renderer As New ChromePdfRenderer()
' Page setup
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginLeft = 20
renderer.RenderingOptions.MarginRight = 20
' Headers and footers with merge fields
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter() With {
.Height = 25,
.HtmlFragment = "<div style='text-align: center; font-size: 12px;'>Page {page} of {total-pages}</div>"
}
' JavaScript execution delay for dynamic content
renderer.RenderingOptions.WaitFor = New WaitFor() With {
.RenderDelay = 500, ' Wait 500ms for JS execution
.NetworkIdle = NetworkIdleTypes.NetworkIdle0 ' Wait for network requests
}
' Apply watermark
renderer.RenderingOptions.TextHeader = New TextHeaderFooter() With {
.DrawDividerLine = True,
.CenterText = "CONFIDENTIAL",
.Font = New FontTypes() With {.FontSize = 16}
}
흔히 발생하는 컨트롤러 오류는 무엇인가요?
일반적인 오류로는 서비스가 제대로 주입되지 않았을 때 발생하는 null 참조 예외, 뷰 위치를 지정할 때 발생하는 경로 문제, 모델 바인딩 문제 등이 있습니다. 모든 필요한 서비스를 Program.cs에 등록하고 뷰 위치를 지정할 때 프로젝트 루트에서 상대 경로를 사용하세요. 문제 해결을 위해 개발자 모드에서 자세한 오류 메시지를 활성화하십시오.
뷰를 추가하는 방법은 무엇인가요?
- 새로 추가된
Person액션을 마우스 오른쪽 버튼으로 클릭하고 ''Add View''를 선택하세요.

- 새 비계 항목에 대해 "Razor 뷰"를 선택하십시오.

- ''List'' 템플릿과
Person모델 클래스를 선택하세요.

이것은 Persons라는 이름의 .cshtml 파일을 만듭니다.
- ''Views'' 폴더로 이동 -> ''Home'' 폴더 ->
Persons.cshtml파일.
Persons 액션을 호출하는 버튼을 추가하려면 아래 코드를 사용하세요:
@using (Html.BeginForm("Persons", "Home", FormMethod.Post))
{
<input type="submit" value="Print Person" />
}
@using (Html.BeginForm("Persons", "Home", FormMethod.Post))
{
<input type="submit" value="Print Person" />
}
PDF 생성에 FormMethod.Post를 사용하는 이유는 무엇일까요?
PDF 생성을 위해 POST를 사용하는 것은 동작을 명시적으로 하고 브라우저 새로 고침이나 북마크된 URL로 인한 원치 않는 PDF 생성을 방지하여 웹 모범 사례를 따릅니다. GET 요청은 서버 상태를 변경하지 않는 멱등성(idempotent)이어야 하며, POST 요청은 결과를 생성하는 작업을 나타냅니다. 이 경우, PDF 문서 생성입니다.
PDF 인쇄 버튼의 스타일을 어떻게 지정할 수 있나요?
CSS 클래스를 사용하여 인쇄 버튼의 스타일을 지정하고 JavaScript 활용하여 사용자 경험을 개선하세요. 다음은 개선된 버전입니다.
@using (Html.BeginForm("Persons", "Home", FormMethod.Post, new { @class = "pdf-form" }))
{
<button type="submit" class="btn btn-primary pdf-download-btn">
<i class="fas fa-file-pdf"></i> Download as PDF
</button>
}
<style>
.pdf-download-btn {
background-color: #dc3545;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.pdf-download-btn:hover {
background-color: #c82333;
}
.pdf-download-btn:active {
transform: translateY(1px);
}
</style>
<script>
// Optional: Show loading indicator during PDF generation
document.querySelector('.pdf-form').addEventListener('submit', function() {
const button = this.querySelector('button');
button.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Generating PDF...';
button.disabled = true;
});
</script>
@using (Html.BeginForm("Persons", "Home", FormMethod.Post, new { @class = "pdf-form" }))
{
<button type="submit" class="btn btn-primary pdf-download-btn">
<i class="fas fa-file-pdf"></i> Download as PDF
</button>
}
<style>
.pdf-download-btn {
background-color: #dc3545;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.pdf-download-btn:hover {
background-color: #c82333;
}
.pdf-download-btn:active {
transform: translateY(1px);
}
</style>
<script>
// Optional: Show loading indicator during PDF generation
document.querySelector('.pdf-form').addEventListener('submit', function() {
const button = this.querySelector('button');
button.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Generating PDF...';
button.disabled = true;
});
</script>
PDF에 가장 적합한 보기 템플릿은 무엇인가요?
List 및 Details 템플릿은 구조화된 레이아웃을 제공하여 PDF 생성에 특히 적합합니다. PDF 출력에 맞춰 특별히 설계된 사용자 지정 템플릿을 사용하면 최상의 결과를 얻을 수 있습니다. 화면 표시보다는 인쇄 레이아웃에 최적화된 전용 PDF 보기를 만들어 탐색 요소를 제거하고 콘텐츠 표현에 집중하는 것을 고려해 보세요.
상단 탐색 모음에 섹션을 추가하려면 어떻게 해야 하나요?
- 동일한 ''Views'' 폴더에서 ''Shared'' 폴더로 이동 ->
_Layout.cshtml.Person네비게이션 항목을Home다음에 배치하세요.
asp-action 속성의 값이 파일 이름(이 경우 Persons)과 정확히 일치하는지 확인하세요.
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">ViewToPdfMVCCoreSample</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Persons">Person</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">ViewToPdfMVCCoreSample</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Persons">Person</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
asp-action이 정확히 일치해야 하는 이유는 무엇입니까?
asp-action 속성은 ASP.NET Core의 태그 도우미를 사용하여 라우팅 구성에 따라 올바른 URL을 생성합니다. 정확한 일치는 링크가 올바른 컨트롤러 동작으로 연결되도록 보장합니다. 불일치가 발생하면 404 오류가 발생하거나 의도하지 않은 작업으로 연결됩니다. 태그 헬퍼 시스템은 대소문자를 구분하며 컨트롤러의 메서드 이름과 정확히 일치해야 합니다.
내비게이션 링크가 일치하지 않으면 어떻게 되나요?
탐색 링크가 컨트롤러 액션과 일치하지 않으면 사용자는 404 오류를 경험하거나 잘못된 페이지로 이동합니다. ASP.NET Core 개발 과정에서 개발자 예외 페이지에는 자세한 라우팅 오류가 표시됩니다. 실제 운영 환경에서 사용자는 일반적인 오류 페이지를 보게 됩니다. 사용자 경험 저하를 방지하려면 탐색 링크가 컨트롤러 액션 이름과 정확히 일치하는지 항상 확인하십시오.
Program.cs 파일을 어떻게 편집하나요?
IHttpContextAccessor 및 IRazorViewRenderer 인터페이스를 의존성 주입(DI) 컨테이너에 등록하세요. 아래 코드를 참고하세요.
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
// Register IRazorViewRenderer here
builder.Services.AddSingleton<IRazorViewRenderer, RazorViewRenderer>();
// Optional: Configure IronPDF license if you have one
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
// Register IRazorViewRenderer here
builder.Services.AddSingleton<IRazorViewRenderer, RazorViewRenderer>();
// Optional: Configure IronPDF license if you have one
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Imports IronPdf.Extensions.Mvc.Core
Imports Microsoft.AspNetCore.Mvc.ViewFeatures
Dim builder = WebApplication.CreateBuilder(args)
' Add services to the container.
builder.Services.AddControllersWithViews()
builder.Services.AddSingleton(Of IHttpContextAccessor, HttpContextAccessor)()
builder.Services.AddSingleton(Of ITempDataProvider, CookieTempDataProvider)()
' Register IRazorViewRenderer here
builder.Services.AddSingleton(Of IRazorViewRenderer, RazorViewRenderer)()
' Optional: Configure IronPDF license if you have one
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE"
Dim app = builder.Build()
' Configure the HTTP request pipeline.
If Not app.Environment.IsDevelopment() Then
app.UseExceptionHandler("/Home/Error")
' The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts()
End If
app.UseHttpsRedirection()
app.UseStaticFiles()
app.UseRouting()
app.UseAuthorization()
app.MapControllerRoute(
name:="default",
pattern:="{controller=Home}/{action=Index}/{id?}")
app.Run()
서비스를 싱글턴으로 등록하는 이유는 무엇인가요?
싱글톤 서비스는 애플리케이션 수명 동안 한 번 생성되고 재사용되어 IRazorViewRenderer 같은 상태 없는 서비스에 효율적입니다. 이 패턴은 뷰 렌더링 서비스가 요청별 상태를 유지하지 않으므로 메모리 오버헤드를 줄이고 성능을 향상시킵니다. IHttpContextAccessor은 서로 다른 서비스 수명 주기에서도 접근할 수 있도록 싱글톤이어야 합니다.
ITempDataProvider는 무엇에 사용되나요?
ITempDataProvider은 일반적으로 리다이렉트 후 메시지를 표시하기 위해 요청 간에 데이터 저장을 가능하게 합니다. PDF 생성 맥락에서, 이는 뷰를 PDF로 렌더링할 때 뷰 상태가 제대로 유지되도록 보장합니다. CookieTempDataProvider은 이 임시 데이터를 암호화된 쿠키에 저장하여 상태 관리를 위한 안전한 메커니즘을 제공합니다.
대신 스코프가 지정된 서비스를 사용할 수 있을까요?
일부 시나리오에서는 스코프 서비스를 사용할 수도 있지만, IRazorViewRenderer은 요청 관련 상태를 유지하지 않으므로 싱글톤으로 가장 잘 작동합니다. 스코프가 지정된 서비스를 사용하면 요청마다 새 인스턴스가 생성되어 이점 없이 메모리 사용량이 증가합니다. 하지만 뷰에 스코프가 지정된 서비스를 주입해야 하는 경우 런타임 오류를 방지하기 위해 적절한 서비스 수명 관리가 필요합니다.
프로젝트 실행
이 문서에서는 프로젝트를 실행하고 PDF 문서를 생성하는 방법을 보여줍니다. 애플리케이션을 실행할 때 최상위 네비게이션 메뉴를 사용하여 Persons 페이지로 이동한 다음 PDF를 생성하고 다운로드하려면 Print Person 버튼을 클릭하세요.
ASP.NET Core MVC 프로젝트는 어디에서 다운로드할 수 있나요?
이 가이드의 전체 코드를 다운로드하세요. 압축 파일 형태로 제공되며, Visual Studio에서 ASP.NET Core 웹 앱(모델-뷰-컨트롤러) 프로젝트로 열 수 있습니다.
ASP.NET Core MVC 샘플 프로젝트를 다운로드하세요
샘플 프로젝트에는 무엇이 포함되어 있나요?
샘플 프로젝트에는 IronPDF 통합된 완벽하게 구성된 ASP.NET Core MVC 애플리케이션이 포함되어 있으며, 뷰를 PDF로 변환하는 기능을 보여줍니다. 이 모델에는 Person 모델, PDF 생성 논리가 포함된 HomeController, 적절한 Razor 구문이 포함된 Persons 뷰, Program.cs의 모든 필요한 서비스 등록이 포함되어 있습니다. 이 프로젝트에는 PDF 출력에 최적화된 스타일링 및 레이아웃 구성 예시도 포함되어 있습니다.
어떤 Visual Studio 버전을 사용해야 할까요?
.NET 6+ 프로젝트를 최적의 환경에서 사용하려면 Visual Studio 2022(버전 17.0 이상)를 사용하는 것이 좋습니다. Visual Studio Code에 C# 확장 기능을 설치하면 크로스 플랫폼 개발에도 효과적입니다. ASP.NET 및 웹 개발 워크로드가 설치되어 있는지 확인하십시오. 이 프로젝트는 기본적으로 .NET 6.0을 대상으로 하지만, 더 최신 버전으로 업데이트할 수 있습니다.
프로젝트 설정 문제를 어떻게 해결하나요?
일반적인 설치 문제에는 NuGet 패키지 누락, 잘못된 .NET SDK 버전 또는 구성 문제가 포함됩니다. 먼저 dotnet restore 또는 Visual Studio의 패키지 관리자를 통해 NuGet 패키지를 복원하세요. dotnet --version을 사용하여 .NET SDK 버전이 프로젝트 요구 사항과 일치하는지 확인하세요. 라이선스 관련 문제는 라이선스 키 문서를 참조하십시오. 렌더링 문제가 발생하는 경우, 문제 해결 가이드를 참조하여 해결 방법을 확인하십시오.
당신이 할 수 있는 다른 일들을 알아볼 준비가 되셨나요? PDF 변환 방법에 대한 튜토리얼 페이지는 여기에서 확인하세요.
자주 묻는 질문
ASP.NET Core MVC에서 CSHTML 뷰를 PDF로 변환하는 가장 쉬운 방법은 무엇인가요?
가장 쉬운 방법은 IronPDF의 RenderRazorViewToPdf 메서드를 사용하는 것입니다. 이 메서드는 단 한 줄의 코드로 .cshtml 파일을 PDF 문서로 변환할 수 있습니다. 간단히 다음과 같이 호출하면 됩니다. new IronPDF.ChromePdfRenderer().RenderRazorViewToPdf(HttpContext, "Views/Home/Report.cshtml", model).SaveAs("report.pdf");
ASP.NET Core MVC에서 뷰를 PDF로 변환하려면 어떤 NuGet 패키지가 필요합니까?
IronPDF(메인 패키지)와 IronPDF.Extensions.Mvc.Core(확장 패키지) 두 가지 패키지가 필요합니다. 확장 패키지는 ASP.NET Core의 의존성 주입 시스템 및 Razor 뷰 렌더링 파이프라인과의 통합을 위한 특정 기능을 제공합니다.
CSHTML을 PDF로 변환할 때 CSS 스타일과 JavaScript를 적용할 수 있나요?
네, IronPDF는 웹 뷰를 PDF로 렌더링할 때 CSS 스타일링, JavaScript 실행 및 사용자 지정 글꼴을 완벽하게 지원합니다. 이를 통해 반응형 CSS 및 동적 JavaScript 콘텐츠를 포함하여 PDF가 웹 뷰와 동일한 모양과 기능을 유지하도록 보장합니다.
ASP.NET Core MVC 프로젝트에서 뷰를 PDF로 변환하는 주요 단계는 무엇인가요?
워크플로는 다음 5단계로 구성됩니다. 1) IronPDF와 MVC Core 확장 프로그램을 다운로드합니다. 2) 데이터를 저장할 모델 클래스를 추가합니다. 3) 컨트롤러를 수정하여 RenderRazorViewToPdf 메서드를 사용합니다. 4) PDF 렌더링을 위한 뷰(.cshtml 파일)를 생성하거나 수정합니다. 5) 애플리케이션을 실행하여 PDF를 생성합니다.
MVC 패턴에서 뷰를 이용한 PDF 생성은 어떻게 작동하나요?
ASP.NET Core MVC에서 모델은 데이터와 비즈니스 로직을 포함하고, 뷰(.cshtml 파일)는 UI를 제공하고 데이터를 표시하며, 컨트롤러는 요청을 처리하고 IronPDF의 RenderRazorViewToPdf 메서드를 사용하여 뷰에서 PDF 생성을 총괄합니다.

