如何在 C# ASP.NET Core MVC 中將視圖轉換為 PDF
using IronPDF 的 RenderRazorViewToPdf 方法將 ASP.NET Core MVC 視圖轉換為 PDF,該方法可以在 MVC 應用中使用一行程式碼將 .cshtml 文件轉換為高質量的 PDF 文件。
視圖是 ASP.NET Framework中的一個組件,用於在 Web 應用中生成 HTML 標記。 它是模型-視圖-控制器 (MVC) 模式的一部分,常用於 ASP.NET MVC 和 ASP.NET Core MVC 應用。 視圖負責通過動態渲染 HTML 內容向使用者呈現資料。 視圖通常使用 Razor 語法,這是一種將基於伺服器的程式碼嵌入網頁的標記語法,使它們成為建立資料驅動 PDF 文件的強大工具。
快速入門:在 ASP.NET Core 中將 CSHTML 轉換為 PDF
using IronPDF 將 ASP.NET Core MVC 視圖轉換為 PDF。 通過一行程式碼,將您的 .cshtml 文件渲染為 PDF 文件。 將此功能直接整合到您的 MVC 應用中,以實現從動態 HTML 視圖到 PDF 的無縫生成。 按照本指南設置您的環境並開始轉換。
ASP.NET Core Web App MVC (Model-View-Controller) 是由 Microsoft 提供的一個 Web 應用框架,用於使用 ASP.NET Core 構建 Web 應用。
Model:表示資料和業務邏輯,管理資料交互,與資料源通信。View:呈現使用者介面,顯示資料,向使用者渲染資訊。Controller:處理使用者輸入,響應請求,與Model通信,協調模型-視圖交互。
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 視圖渲染系統的專門整合。 這種分離允許更好的模組化,確保您只包含專案型別所需的特定功能。 擴展套件包括將 Razor 視圖轉換為 HTML 所需的 IRazorViewRenderer 介面和實現,在生成 PDF 之前。
我應該使用哪個 NuGet 套件版本?
始終使用 IronPdf 和 IronPdf.Extensions.Mvc.Core 的匹配版本以確保相容性。 有關最新穩定版本和版本相容性資訊,請查看 NuGet 套件文件。 更新時,確保同時更新兩個套件以保持正常功能。
常見的安裝問題有哪些?
常見的安裝問題包括核心和擴展套件之間的版本不匹配、缺少依賴項或平台特定需求。 如果您遇到問題,請確保您的專案針對受支持的 .NET 版本並查看安裝概述以獲取疑難排解步驟。
使用 NuGet 安裝
Install-Package IronPdf.Extensions.Mvc.Core
如何將視圖渲染為 PDF?
您需要一個 ASP.NET Core Web App (Model-View-Controller) 項目來將視圖轉換為 PDF 文件。 此過程涉及建立一個控制器操作,該操作使用 IronPDF 的 RenderRazorViewToPdf 方法將您的 Razor 視圖轉換為 PDF 文件。 這種方法利用 Razor 語法的全部功能,允許您建立複雜的、資料驅動的 PDF,具有動態內容。
應使用哪種型別的專案?
using ASP.NET Core Web App (Model-View-Controller) 模板,以獲得與 IronPDF 視圖渲染功能的最佳相容性。 該專案型別為視圖渲染提供必要的基礎設施,包括 Razor 視圖引擎和適當的路由。 對於現有專案,確保它們遵循 MVC 模式並安裝了必需的視圖渲染功能。
我可以將此功能與 Minimal APIs 一起使用嗎?
雖然 Minimal APIs 沒有內建的視圖支持,但您仍然可以使用 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 輸出設計的 ViewModels。
以下是一個適合 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.cs 文件。我們將僅修改 HomeController 並新增 Persons 操作。 請參考以下程式碼以獲得指導:
下面的程式碼首先實例化 ChromePdfRenderer 類,傳遞IRazorViewRenderer、我們的 Views/Home/Persons.cshtml 路徑和包含所需資料的 List 給 RenderRazorViewToPdf 方法。 使用者可以使用 RenderingOptions 存取一系列功能,例如新增自訂文字、在生成的 PDF 中包含 HTML 標頭和標尾、定義自訂邊距和應用頁碼。 要獲得更多高級渲染選項,請參閱渲染選項文件。
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
using 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 屬性提供廣泛的自訂選項。 以下是一個更高級的設置範例:
:path=/static-assets/pdf/content-code-examples/how-to/cshtml-to-pdf-mvc-core-6.cs
// 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.RenderDelay(500); // Wait 500ms for JS execution
renderer.RenderingOptions.WaitFor.NetworkIdle0(); // Wait for network requests
// Apply watermark
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
DrawDividerLine = true,
CenterText = "CONFIDENTIAL",
Font = IronSoftware.Drawing.FontTypes.Arial,
FontSize = 16
};
Imports IronPdf
Imports IronSoftware.Drawing
' Advanced rendering configuration example
Dim 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() 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.RenderDelay(500) ' Wait 500ms for JS execution
renderer.RenderingOptions.WaitFor.NetworkIdle0() ' Wait for network requests
' Apply watermark
renderer.RenderingOptions.TextHeader = New TextHeaderFooter() With {
.DrawDividerLine = True,
.CenterText = "CONFIDENTIAL",
.Font = FontTypes.Arial,
.FontSize = 16
}
常見的控制器錯誤有哪些?
常見錯誤包括服務未正確注入時的空引用異常,指定視圖位置時的路徑問題,以及模型綁定問題。 確保所有所需的服務均已在 Program.cs 中註冊,並在指定視圖位置時使用專案根目錄的相對路徑。 為故障排除,在開發模式下啟用詳細錯誤消息。
如何新增視圖?
- 右鍵點擊新新增的
Person操作並選擇"新增視圖"。

- 為新建立的模板選擇"Razor 視圖"。

- 選擇"列表"模板和
Person模型類。

這會建立一個名為 .cshtml 的 Persons 文件。
- 導航到"Views"文件夾 -> "Home"文件夾 ->
Persons.cshtml文件。
IronPdf.Extensions.Mvc.Core
要新增一個調用 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" />
}
為何使用 FormMethod.Post 進行 PDF 生成?
using FormMethod.Post 來生成 PDF 遵循 Web 的最佳實踐,通過使該操作明確拒絕來防止來自瀏覽器刷新或收藏網址的無意 PDF 生成。 POST 請求應具有冪等性(不改變伺服器狀態),而 POST 請求則表示生成結果的行為——在此案例中,生成 PDF 文件。
如何設計 PDF 列印按鈕?
using 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 視圖,這些視圖優化為列印佈局而不是螢幕顯示,去除導航元素並專注於內容呈現。
如何向頂部導航欄中新增部分?
- 在相同的"視圖"文件夾中,導航到"共享"文件夾 ->
_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) 容器中。 請參閱下面的程式碼以獲得參考。
:path=/static-assets/pdf/content-code-examples/how-to/cshtml-to-pdf-mvc-core-10.cs
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()
為何需要將服務註冊為 Singleton?
單例服務在應用的整個生命週期內建立一次並重用,對於 @--CODE-599--@@ 這類無狀態的服務是高效的。 因為視圖渲染服務不維持請求特定的狀態,這種模式減少了記憶體開銷並提升了性能。 必須是單例以便能在不同的服務生命週期中被存取。
ITempDataProvider 的用途是什麼?
ITempDataProvider 使得跨請求的臨時資料儲存變得可能,通常用於在重定向後顯示訊息。 在 PDF 生成的上下文中,這確保視圖狀態在渲染視圖到 PDF 時得到正確維護。 CookieTempDataProvider 將這些臨時資料儲存在加密的 Cookie 中,提供了一種安全的狀態管理機制。
我可以改用 Scoped Services 嗎?
雖然您可以在某些場景中使用 Scoped Services,但由於 IRazorViewRenderer 並不持有請求特定的狀態,作為單例服務最佳。 使用 Scoped Services 會為每個請求建立新實例,增加了記憶體使用,但卻沒有好處。 不過,如果您需要將 Scoped Services 注入到視圖中,請確保正確的服務生命週期管理以避免運行時錯誤。
運行項目
這顯示了如何運行項目並生成 PDF 文件。 當您運行應用時,使用頂部導航選單導航到 Persons 頁面,然後點擊 Print Person 按鈕來生成並下載 PDF。
我可以在哪裡下載 ASP.NET Core MVC 項目?
下載本指南的完整程式碼。它作為一個壓縮文件,可以在 Visual Studio 中打開作為 ASP.NET Core Web App (Model-View-Controller) 項目。
範例項目中包含了什麼?
範例項目包括一個與 IronPDF 整合的完整配置的 ASP.NET Core MVC 應用,演示從視圖到 PDF 的轉換。 它包含 Person 模型、HomeController 具有 PDF 生成邏輯、具有正確 Razor 語法的 Persons 視圖以及在 Program.cs 中的所有必要服務註冊。 該專案還包括針對 PDF 輸出優化的樣式和佈局配置範例。
我應該使用哪個 Visual Studio 版本?
建議使用 Visual Studio 2022(版本 17.0 或更高)以獲得 .NET 6+ 項目最佳體驗。 Visual Studio Code 與 C# 擴展也非常適合跨平台開發。 確保您安裝了 ASP.NET 和 Web 開發工作負載。 該項目預設情況下針對 .NET 6.0,但可以更新到更新的版本。
如何排除項目設置問題的故障?
常見的設置問題包括缺少 NuGet 套件、不正確的 .NET SDK 版本或配置問題。 首先,使用 dotnet restore 或通過 Visual Studio 的套件管理器恢復 NuGet 套件。 確認您的 .NET SDK 版本與項目要求匹配,使用 dotnet --version。 有關許可問題,請參閱許可金鑰文件。 如果發生渲染問題,請檢查故障排除指南以獲得解決方案。
準備好看看您還能做什麼嗎? 在此查看我們的教程頁面:轉換PDF
常見問題
在ASP.NET Core MVC中將CSHTML視圖轉換為PDF的最簡單方法是什麼?
最簡單的方法是使用IronPDF的RenderRazorViewToPdf方法,它可以用一行程式碼將您的.cshtml檔案轉換為PDF文件。 只需調用:new IronPdf.ChromePdfRenderer().RenderRazorViewToPdf(HttpContext, "Views/Home/Report.cshtml", model).SaveAs("report.pdf");
我需要哪些NuGet包才能在ASP.NET Core MVC中將視圖轉換為PDF?
您需要兩個包:IronPdf(主要包)和IronPdf.Extensions.Mvc.Core(擴展包)。 擴展包提供了特定的功能,以便與ASP.NET Core的依賴注入系統和Razor視圖渲染管道整合。
將CSHTML轉換為PDF時,我可以應用CSS樣式和JavaScript嗎?
可以,IronPDF完全支持CSS樣式,JavaScript執行以及自定義字體渲染視圖為PDF。 這確保您的PDF保持與網頁視圖相同的外觀和功能,包括響應式CSS和動態JavaScript內容。
在我的ASP.NET Core MVC專案中實施視圖到PDF轉換的主要步驟有哪些?
工作流程涉及五個步驟:1)下載IronPDF及其MVC Core擴展,2)為資料新增模型類,3)編輯您的控制器以使用RenderRazorViewToPdf方法,4)建立或修改用於PDF渲染的視圖(.cshtml檔案),5)運行您的應用程式以生成PDF。
MVC模式如何在從視圖生成PDF中工作?
在ASP.NET Core MVC中,模型包含資料和業務邏輯,視圖(您的.cshtml檔案)提供UI並顯示資料,控制器處理請求並使用IronPDF的RenderRazorViewToPdf方法來協調從視圖生成PDF。

