如何在 ASP.NET Core MVC 中将视图转换为 PDF | IronPDF for .NET

如何在 C# ASP.NET Core MVC 中将视图转换为 PDF

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

使用 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

使用 IronPDF for .NET 将 ASP.NET Core MVC 视图转换为 PDF。 只需一行代码,即可将您的".cshtml "文件渲染为 PDF 文档。 将此功能直接集成到您的 MVC 应用程序中,以便从动态 HTML 视图无缝生成 PDF。 请按照本指南设置环境并开始转换。

  1. 使用 NuGet 包管理器安装 https://www.nuget.org/packages/IronPdf

    PM > Install-Package IronPdf
  2. 复制并运行这段代码。

    // using IronPdf.Extensions.Mvc.Core
    new IronPdf.ChromePdfRenderer().RenderRazorViewToPdf(HttpContext, "Views/Home/Report.cshtml", model).SaveAs("report.pdf");
  3. 部署到您的生产环境中进行测试

    通过免费试用立即在您的项目中开始使用IronPDF

    arrow pointer

ASP.NET Core Web App MVC(模型-视图-控制器)是微软提供的一个 Web 应用程序框架,用于使用 ASP.NET Core 构建 Web 应用程序。

  • 模型:代表数据和业务逻辑,管理数据交互,与数据源通信。
  • 视图:提供用户界面、显示数据、向用户呈现信息。
  • 控制器:处理用户输入、响应请求、与模型通信、协调模型与视图的交互。

IronPDF 可在 ASP.NET Core MVC 项目中通过视图直接创建 PDF 文件。 这使得 PDF 生成在 ASP.NET Core MVC 中变得简单明了,支持包括 CSS 风格JavaScript 执行 自定义字体在内的现代功能。

IronPDF 扩展需要哪些软件包?

IronPdf.Extensions.Mvc.Core 包是主 IronPdf 包的扩展。 在ASP.NET Core MVC 中,要将视图渲染为 PDF 文档,需要 IronPdf.Extensions.Mvc.CoreIronPdf 包。 扩展包提供了与 ASP.NET Core 的依赖注入系统和 Razor 视图渲染管道集成的特定功能。

安装-打包 IronPdf.Extensions.Mvc.Core

为什么我需要 IronPDF 和扩展包?

IronPDF 的主软件包包含核心 PDF 渲染引擎和基本功能,而 Extensions.Mvc.Core 软件包则提供与 ASP.NET Core MVC 的视图渲染系统的专门集成。 这种分离可以实现更好的模块化,确保只包含项目类型所需的特定功能。 该扩展包包含将Razor视图转换为 HTML 后再生成 PDF 所需的 IRazorViewRenderer 接口和实现。

我应该使用哪个 NuGet 软件包版本?

为确保兼容性,请始终使用匹配版本的IronPDF和 IronPdf.Extensions.Mvc.Core。 有关最新稳定版本和版本兼容性信息,请查看 NuGet 软件包文档。 更新时,确保两个软件包一起更新,以保持适当的功能。

常见的安装问题有哪些?

常见的安装问题包括核心软件包和扩展软件包之间的版本不匹配、依赖关系缺失或特定平台要求。 如果遇到问题,请确保您的项目使用的是受支持的 .NET 版本,并查看安装概述以了解故障排除步骤。

C# 用于 PDF 的 NuGet 库

通过 NuGet 安装

Install-Package IronPdf.Extensions.Mvc.Core

如何将视图渲染为 PDF?

您需要一个 ASP.NET Core Web App(模型-视图-控制器)项目来将视图转换为 PDF 文件。 该过程涉及创建一个控制器操作,该操作使用 IronPDF 的 RenderRazorViewToPdf 方法将Razor视图转换为 PDF 文档。 这种方法充分利用了 Razor 语法的全部功能,使您能够创建具有动态内容的复杂、数据驱动型 PDF。

我应该使用哪种项目类型?

使用 ASP.NET Core Web App(模型-视图-控制器)模板,以获得与 IronPDF 视图渲染功能的最佳兼容性。 该项目类型为视图渲染提供了必要的基础设施,包括 Razor 视图引擎和适当的路由。 对于现有项目,应确保它们遵循 MVC 模式并安装了所需的视图渲染功能。

我可以使用最小化 API 吗?

虽然 Minimal API 没有内置视图支持,但您仍然可以使用 IronPdf 的 HTML 到 PDF 转换功能。 对于基于视图的 PDF 生成,请使用传统的 MVC 方法或考虑将 Razor Pages 作为替代方法。

如何添加模型类?

  • 导航到"Models"文件夹。
  • 创建一个新的 C# 类文件,命名为 "Person"。该类将作为表示个人数据的模型。 使用以下代码片段:
: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; }
    }
}
$vbLabelText   $csharpLabel

为什么我需要生成 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; }
}
$vbLabelText   $csharpLabel

如何编辑控制器?

导航至"Controllers"文件夹并打开"HomeController"文件。我们将仅对Persons操作。 请参考以下代码以获得指导:

下面的代码首先实例化 ChromePdfRenderer 类,将 IRazorViewRenderer、我们的 Views/Home/Persons.cshtml 的路径以及包含所需数据的列表传递给 RenderRazorViewToPdf 方法。 用户可以使用 RenderingOptions 访问一系列功能,例如添加自定义文本、在生成的 PDF 中添加 HTML 页眉和页脚、定义自定义边距以及应用页码。 有关更多高级渲染选项,请参阅渲染选项文档。

请注意可以使用以下代码在浏览器中查看 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 });
        }
    }
}
$vbLabelText   $csharpLabel

使用 RenderRazorViewToPdf 方法后,您将收到一个 PdfDocument 对象,该对象可以进行进一步的增强和修改。 您可以将 PDF 转换为 PDF/A 或 PDF/UA 格式,在生成的 PDF 上添加数字签名,或根据需要合并和拆分 PDF 文档。 此外,该库允许您旋转页面,插入注释或书签,并在您的 PDF 文件上加盖独特的水印。

什么是 IRazorViewRenderer 服务?

IRazorViewRendererIronPdf.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 }
};
$vbLabelText   $csharpLabel

哪些是常见的控制器错误?

常见错误包括服务未正确注入时的空引用异常、指定视图位置时的路径问题以及模型绑定问题。 确保所有必需的服务都已在 Program.cs 中注册,并在指定视图位置时使用相对于项目根目录的相对路径。 为排除故障,请在开发模式下启用详细的错误信息。

如何添加视图?

  • 右键单击​​新添加的 Person 操作,然后选择"添加视图"。

在右键单击 Persons() 方法时,Visual Studio 上下文菜单中的

  • 为新的脚手架项选择"Razor View"。

在 Visual Studio 中添加Razor View 对话框,显示列表模板和 Person 模型类选择以及布局选项

  • 选择"列表"模板和 Person 模型类。

在 Visual Studio 中添加Razor View 对话框,显示 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" />
}
HTML

为什么使用 FormMethod.Post 生成 PDF?

使用 POST 生成 PDF 遵循 Web 最佳实践,明确操作,防止因浏览器刷新或书签 URL 而生成不必要的 PDF。 GET 请求应该是幂等的(不改变服务器状态),而 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>
HTML

哪些视图模板最适合 PDF?

ListDetails 模板特别适合生成 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>
HTML

为什么 asp-action 需要完全匹配?

asp-action 属性使用ASP.NET Core 的标记助手,根据您的路由配置生成正确的 URL。 精确匹配可确保链接指向正确的控制器操作。 不匹配会导致 404 错误或路由到非预期的操作。 标签辅助系统区分大小写,必须与控制器中的方法名称完全匹配。

如果导航链接不匹配会怎样?

当导航链接与控制器操作不匹配时,用户会遇到 404 错误或被引导到不正确的页面。 在开发过程中,ASP.NET Core 的开发人员异常页面会显示详细的路由错误。 在生产过程中,用户会看到通用的错误页面。 务必确保导航链接与控制器操作名称完全匹配,以防止破坏用户体验。

如何编辑 Program.cs 文件?

IHttpContextAccessorIRazorViewRenderer 接口注册到依赖注入 (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();
$vbLabelText   $csharpLabel

为什么要将服务注册为单例?

单例服务创建一次,并在应用程序的整个生命周期内重复使用,因此对于像 IRazorViewRenderer 这样的无状态服务来说非常高效。 这种模式可以减少内存开销并提高性能,因为视图呈现服务不需要维护请求的特定状态。 IHttpContextAccessor 必须是单例才能在不同的服务生命周期中访问。

ITempDataProvider 有何用途?

ITempDataProvider 允许在请求之间临时存储数据,通常用于在重定向后显示消息。 在生成 PDF 时,要确保在将视图渲染为 PDF 时正确保持视图状态。 CookieTempDataProvider 将此临时数据存储在加密 cookie 中,为状态管理提供安全机制。

我可以使用范围服务来代替吗?

虽然在某些情况下可以使用作用域服务,但 IRazorViewRenderer 作为单例效果最佳,因为它不保存请求特定的状态。 使用范围服务会为每个请求创建新的实例,增加内存使用量,却没有任何好处。 不过,如果您需要在视图中注入作用域服务,请确保正确的服务生命周期管理,以避免运行时出错。

运行项目

这展示了如何运行项目并生成 PDF 文档。 运行应用程序时,使用顶部导航菜单导航到 Persons 页面,然后单击 Print Person 按钮生成并下载 PDF。

Visual Studio showing HomeController.cs with ASP.NET Core MVC controller code and IntelliSense assistance

在哪里可以下载 ASP.NET Core MVC 项目?

下载本指南的完整代码。它以压缩文件的形式提供,您可以在 Visual Studio 中将其作为 ASP.NET Core Web App(模型-视图-控制器)项目打开。

下载 ASP.NET Core MVC 示例项目

示例项目包括哪些内容?

示例项目包括一个完整配置的 ASP.NET Core MVC 应用程序,其中集成了 IronPDF,演示了视图到 PDF 的转换。 它包含 Person 模型、HomeController 以及 PDF 生成逻辑、Persons 以及具有正确Razor语法的视图,以及 Program.cs 中的所有必要服务注册。 该项目还包括针对 PDF 输出进行优化的样式和布局配置示例。

我应该使用哪个 Visual Studio 版本?

建议使用 Visual Studio 2022(17.0 或更高版本),以获得 .NET 6+ 项目的最佳体验。 带有 C# 扩展的 Visual Studio Code 也能很好地进行跨平台开发。 确保您已安装 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 执行和自定义字体。这可确保您的 PDF 保持与网页视图相同的外观和功能,包括响应式 CSS 和动态 JavaScript 内容。

在我的 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 文件)呈现用户界面并显示数据,控制器处理请求并使用 IronPDF 的 RenderRazorViewToPdf 方法协调视图生成 PDF。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

审核者
Jeff Fritz
Jeffrey T. Fritz
首席项目经理 - .NET 社区团队
Jeff 也是 .NET 和 Visual Studio 团队的首席项目经理。他是 .NET Conf 虚拟会议系列的执行制片人,并主持“Fritz and Friends”直播节目,每周两次与观众一起谈论技术并编写代码。Jeff 撰写研讨会、演示文稿并计划包括 Microsoft Build、Microsoft Ignite、.NET Conf 和 Microsoft MVP 峰会在内的最大型微软开发者活动的内容。
准备开始了吗?
Nuget 下载 17,803,474 | 版本: 2026.3 刚刚发布
Still Scrolling Icon

还在滚动吗?

想快速获得证据? PM > Install-Package IronPdf
运行示例看着你的HTML代码变成PDF文件。