使用EZFontResolver(PDFsharp)设置字体解析器时抛出异常
解决PDFsharp v1.51在ASP.NET MVC中设置EZFontResolver的异常问题
异常*Must not change font resolver after is was once used.*的核心原因是ASP.NET MVC是多请求并发环境,你当前的代码在每次请求的GetCertificate方法中重复设置全局的GlobalFontSettings.FontResolver——而PDFsharp要求字体解析器只能被设置一次,第一次请求触发初始化后,后续请求再赋值就会抛出异常。
1. 移至应用启动时初始化字体解析器
将字体解析器的初始化和字体添加操作,放到应用启动阶段(仅执行一次),比如Global.asax.cs的Application_Start方法:
protected void Application_Start() { // 初始化EZFontResolver单例并设置为全局解析器 var fontResolver = EZFontResolver.Get; GlobalFontSettings.FontResolver = fontResolver; // 添加私有字体,确保路径正确(可通过Web.config配置路径) string fontPath = Server.MapPath("~/fonts/PinyonScript-Regular.ttf"); fontResolver.AddFont("Pinyon Script", XFontStyle.Regular, fontPath, true, true); // 其他MVC初始化逻辑 AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); // ... }
2. 修改请求方法,移除重复设置逻辑
在GetCertificate方法中,不再重复设置字体解析器,直接使用已初始化好的全局实例:
public byte[] GetCertificate(Object model) { // 无需再次设置FontResolver,直接创建文档即可 var document = new PdfDocument(); document.Info.Title = "CERTIFICATE "; // 后续绘制逻辑中直接使用"Pinyon Script"字体 // 示例: // var page = document.AddPage(); // var gfx = XGraphics.FromPdfPage(page); // var font = new XFont("Pinyon Script", 24, XFontStyle.Regular); // gfx.DrawString("Certificate Text", font, XBrushes.Black, new XPoint(100, 100)); // ... 剩余代码 }
3. 额外注意事项
- 路径正确性:确保在应用启动时能正确获取字体文件路径(使用
Server.MapPath或配置文件指定绝对路径),避免运行时找不到字体。 - 线程安全:如果需要添加多个字体,务必在应用启动时一次性完成,不要在请求处理过程中动态添加(若必须动态添加,需自行修改EZFontResolver实现,确保线程安全)。
- 单例约束:PDFsharp的
GlobalFontSettings是静态全局对象,字体解析器一旦设置并被使用后就不可修改,这是框架的设计约束,必须严格遵守。
内容的提问来源于stack exchange,提问作者Romias
相关产品推荐
相关产品推荐

