迁移
Doconut.NETFramework 26.8.0 (.NET Framework 4.7) 到 26.9.0 (.NET Framework 4.7.2)
本文档介绍如何将现有的 ASP.NET 应用程序从 Doconut.NETFramework 26.8.0 或更早版本(.NET Framework 4.7)升级到 26.9.0 及以后版本(.NET Framework 4.7.2)。Doconut 示例包包含完整的迁移指南以及已移植到新 API 的经典示例——MVC 5、Web 农场和 Web Forms。将你的应用程序与它所基于的示例进行对比是最快的迁移路径。
一个包,两个版本
两个库使用相同的包标识符 Doconut.NETFramework。版本号用于区分它们:
| 版本 | 目标 | API |
|---|---|---|
| 26.8.0 及更早 | .NET Framework 4.7 | 之前的 API |
| 26.9.0 及以后 | .NET Framework 4.7.2 | 新的 API |
更新包即完成升级。没有单独的安装包,也没有兼容层:26.9.0 是不同的 API 表面,更新后会出现编译错误——请参阅本页后续内容。.NET Framework 4.7 系列已停止维护,26.8.0 是其最后一次发布。你可以继续使用它——这里没有任何安全修复会因此错过——但新版本、插件、分布式模式以及即插即用小部件仅在 26.9.0 及以后提供。
1. 重新定位并更新包
首先将 Web 项目重新定位到 .NET Framework 4.7.2:仍然定位到 4.7 的项目无法安装 26.9.0,NuGet 会拒绝更新。随后更新 Doconut.NETFramework 并添加你使用的插件包(Doconut.NETFramework.Converter、Doconut.NETFramework.Dicom,……)。每个插件都需要相应的授权许可。
如果项目使用 packages.config,更新过程会执行之前版本的卸载步骤,移除 DocImage 处理程序(位于 Web.config),而 26.9.0 并不会重新添加。请按照第 3 步重新注册;在此之前,DocImage.axd 会返回 404,页面无法渲染。
2. 命名空间:几乎所有内容都迁移到根命名空间
| 之前 | 现在 |
|---|---|
using Doconut.Configs.View; | using Doconut; |
using Doconut.Models; | using Doconut; |
using Doconut.Configs; | using Doconut; |
using Doconut.Configs.Cloud; | using Doconut.Clouds; |
using Doconut.Configs.Conversion; | unchanged |
类型名称未变:WordConfig、PdfConfig、ExcelConfig、CssConfig、ScriptConfig、FileShareConfig 以及其余类型仍然存在。大多数文件只需删除 using 行即可完成迁移。
3. 启动:DoconutHost.Initialize 与两个 Web.config 条目
经典包在每次请求时构建查看器实例,选项作为该实例的属性。新包采用组合根模式,在 Application_Start 中构建一次,查看器则作为可解析的服务:
// 之前 - Doconut.NETFramework 26.8.0 及更早版本,按请求
var viewer = new Viewer
{
ID = "ctlDoc",
IncludeJQuery = true,
BasePath = "/",
FitType = "width"
};// Doconut.NETFramework 26.9.0\u002B - 查看器从 DoconutHost 解析,许可证在 DoconutHost.Initialize() 中配置一次
var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { AllowSearch = true });DoconutHost.Initialize 放入 Application_Start,DoconutHost.Shutdown 放入 Application_End,并且 Web.config 获得 DocImage.axd 处理程序和资源模块——两者均在安装章节中。每页外观设置(FitType、FixedZoom、ShowHyperlinks,……)从查看器实例迁移到小部件的选项,或迁移到传递给 Viewer.RenderViewer 的 ViewerConfig(参见查看器配置)。new Viewer() 仍然在 DoconutHost.Initialize 运行后编译一次,因此迁移后的代码后置仍可保留该行,同时你可以移动设置。
安全性保持不变。 打开文档会授予当前 ASP.NET 会话访问其页面的权限,DocImage.axd 会拒绝其他所有请求。原先用于关闭此功能的 DoconutUnSafeMode 应用设置现在改为 options.UnsafeMode,位于 DoconutHost.Initialize——请保持其 false。详见会话与安全。
导致整个站点宕机的启动失败。 某个已注册插件的功能未获得授权时会在
Application_Start抛出异常,随后应用对每个请求返回空的500——没有错误页面,IIS 日志中也没有记录,仅在 Windows 事件日志(来源 ASP.NET)中留下条目。许可证从站点根目录下的wwwroot读取,其他位置不读取;且必须存在基础的Doconut.Viewer.lic,否则插件旁边的许可证也不会被读取。详见许可证设置。
4. Web 农场:从标记到分布式模式
经典模型是 viewer.IsWebfarm = true 加 ExportToPng(path)。新模型只需注册一次:所有节点共享同一个存储和签名密钥,一个绑定到浏览器的已签名票据取代 “哪个节点响应”:
Doconut.DoconutHost.Initialize(
options => options.UnsafeMode = false,
services => services.AddDoconutDistributed(d =>
{
d.Store = CloudLocation.FileShare;
d.FileShareRootPath = @"\\fileserver\doconut-shared"; // WebfarmPath 是别名
d.SigningKey = farmKey; // >= 32 字节,在每个节点上相同
}));然后像往常一样打开文档,绑定浏览器(DocOptions.BrowserId = DoconutFarmBinding.EnsureBrowserId(...))并将 viewer.AccessToken 交给带有令牌的小部件。会话与安全 中有步骤说明;Web 农场 示例是完整的节点。IsWebfarm 和 WebfarmPath 仍然可以编译,但它们不再切换任何东西。
有两件看起来像成功却并非如此的事:DistributedDocumentPublisher.PublishAsync 会写入文档的渲染文件但不打开会话,所以指向已发布令牌的查看器会得到约 2 KB、状态码 200 的错误图片;没有 doconut-client Cookie 的测试客户端也会得到同样的图片,而不是 401。通过大小可以区分真实页面和错误图片。
5. 转换是插件,且体积更小
SourceFormatConverter 枚举、十二个 *ConfigConverter 类以及它们的嵌套目标枚举被一个枚举 ConversionTarget 和一次调用取代:
using System.IO;
using System.Threading;
using Doconut;
using Doconut.Configs.Conversion;
// 假设 DoconutHost 已经初始化,并且一个名为 ct 的 CancellationToken 可用。
var provider = DoconutHost.Services;
var converter = (DocumentConverter)provider.GetService(typeof(DocumentConverter));
Stream source = /* 你的输入流 */;
var result = await converter.ConvertAsync(source, ".dwg", ConversionTarget.Pdf, null, ct);源格式来自你传入的扩展名。没有兼容层:每个 SourceFormatConverter 引用都会导致编译错误,你只能通过删除它来解决。按格式的选项对象未能保留——WordConfigConverter.HtmlOptions 和 CadConfigConverter.CadOptions.ShowColor 通过 ConvertAsync 没有等价实现。在 Web 表单 中,永远不要在 ConvertAsync 上阻塞——参见 转换插件。
6. 云存储:将其视为 共享文件夹
云配置类型保持不变,仍然移动到 Doconut.Clouds。然而云请求处理程序是 ASP.NET Core 组件,经典应用没有管道来运行它们。从 System.Web 站点出发,可将云存储视为 共享文件夹——在 Azure 上,即挂载到每个节点的 Azure Files 共享——通过 FileShareConfig 访问。
7. 客户端更改静默失败
下面的每一项都能编译、运行、没有日志输出,却做错了事:
| 之前 | 现在 |
|---|---|
ResPath: 'doconut-res' | ResPath: 'doconut-res/images' — 否则每个图标在文档渲染时都会返回 404 |
function ctlDoc_ViewerReady() { } | docViewer({ onViewerReady: function () { } }) — 查看器回调现在是可选的 |
var viewer = $(el).docViewer({...}).View(token) | 先分配 docViewer(...),然后单独调用 viewer.View(token) |
viewer.Refit() 以适应页面 | viewer.FitType('width') — Refit() 只重新计算布局 |
var n = viewer.Search(kw, exact) | viewer.Search(kw, exact, function (n) { … }) — 计数在回调中到达 |
if (viewer.SaveAnnotations()) { … } | docViewer({ onAnnSaved: …, onAnnSaveError: … }) |
function ctlDoc_Created() { } (annotations) | 未更改 — 注释事件函数仍然是全局的,按名称查找 |
另外还有三点:查看器不会绘制自己的工具栏(你的页面将 Zoom、Next、GotoPage 以及其余部分绑定到自己的按钮);在隐藏的 Bootstrap 模态框中创建的查看器尺寸为 0×0,直到为其容器显式设定高度并在 shown.bs.modal 上重新适配后才会绘制;并且 AllowSearch 对 PDF 默认使用 false,因此文档可以完美渲染,而每次搜索都返回空结果。
8. 什么消失了
| 已移除 | 取而代之 |
|---|---|
DocumentSearch / TextSearch.cs | 无 — 搜索在格式查看器提取的文本上运行 |
Viewer.WatermarkInfo | 无等价项 |
WordConfigConverter.HtmlOptions | 没有通过 ConvertAsync 的选项对象 |
SourceFormatConverter,*ConfigConverter 类 | ConversionTarget 和 ConvertAsync |
Doconut.Configs.Editor | 已移除 |
viewer.IsWebfarm + ExportToPng(path) | AddDoconutDistributed 和普通打开 |
建议的工作顺序
- 重新定位,替换包,并使
Global.asax在DoconutHost.Initialize和两个Web.config注册下编译成功。站点应当启动。 - 一个查看器页面:获取文档进行渲染,然后完成第 7 节,直到工具栏、搜索和注释正常工作。在真实浏览器中验证 — 该章节中没有任何错误抛出。
- 转换(第 5 节):机械式的,并且大多数编译错误。
- 其余页面,使用已移植的示例作为差异目标。
- Web 农场(第 4 节),如果你有的话。使用两个节点和浏览器,或保持 cookie 的客户端进行测试。
此页面对您有帮助吗?