Di chuyển sang .NET Standard 2.1

Di chuyển một ứng dụng Doconut.NETStandard hiện có từ 26.7.0 lên 26.8.0

Doconut có hai tích hợp .NET Standard riêng biệt. Chúng sử dụng cùng một tên gói Doconut.NETStandard, vì vậy hãy xác định thế hệ dựa trên phiên bản và các API trong ứng dụng trước khi thay đổi gói, khởi động, giấy phép hoặc tài nguyên trình duyệt.

Phiên bản là ngã rẽ

Cả hai thế hệ đều phát hành dưới cùng một ID gói. Chỉ có phiên bản mới phân biệt chúng:

Phiên bảnMục tiêuAPI
26.7.0 và các phiên bản thấp hơnnetstandard2.0API trước
26.8.0 và các phiên bản cao hơnnetstandard2.1API hiện tại

Tăng số phiên bản là việc nâng cấp. Không có gói riêng để cài đặt và không có shim tương thích — 26.8.0 là một bề mặt API khác. Hãy chuẩn bị cho các lỗi biên dịch sau khi tăng phiên bản; phần còn lại của hướng dẫn này là danh sách các lỗi đó.

Bạn đang sử dụng tích hợp nào?

Nếu dự án chứa…Thế hệ
new Viewer(_cache, _accessor, ...)Trước
viewer.OpenDocument(...) (synchronous)Trước
viewer.InitCache()Trước
UseDoconut(new DoconutOptions { ... })Trước
UseDoconutWebFarm(...) / WebFarmOptionsTrước
Viewer.DoconutLicense(...) hoặc Viewer.SetLicensePlugin(...)Trước
viewer.Converter.GetConverter()Trước
using Doconut.Configs; / using Doconut.Models;Trước
Sao chép thủ công docViewer.js, documentLinks.js, hoặc docViewer.UI.jsTrước
builder.Services.AddDoconut(...)Hiện tại
app.UseDoconutResources() và app.UseDoconut() không có đối sốHiện tại
Viewer được cung cấp qua tiêm phụ thuộcHiện tại
await viewer.OpenDocumentAsync(...)Hiện tại

Nếu cả hai cột xuất hiện trong cùng một ứng dụng, coi việc di chuyển là chưa hoàn chỉnh. Đừng gửi một token tài liệu qua tài nguyên hoặc middleware từ thế hệ khác.

Kiểm tra khung nền tảng máy chủ trước

Đây là một rào cản cứng, không phải sở thích. Gói hiện tại nhắm tới netstandard2.1:

Nền tảngCó thể tiêu thụ 26.8.0
.NET Core 3.0 hoặc các phiên bản sau (bao gồm .NET 5/6/7/8)Có
.NET Framework, bất kỳ phiên bản nàoKhông

.NET Framework không thể tham chiếu một thư viện netstandard2.1. Nếu ứng dụng chạy trên .NET Framework, dừng lại ở đây và sử dụng gói Doconut.NETFramework thay thế; từ phiên bản 26.9.0 nó yêu cầu .NET Framework 4.7.2. Cả hai ứng dụng tham chiếu cho bản phát hành này đều nhắm tới net8.0.

Trước khi di chuyển

  1. Tạo một nhánh và bản sao lưu có thể triển khai của ứng dụng hiện có.
  2. Ghi lại các phiên bản gói core và plugin chính xác.
  3. Kiểm kê mọi lời gọi new Viewer(...), lời gọi InitCache(), lời gọi tải giấy phép, ánh xạ UseDoconutWebFarm, bộ điều khiển chuyển đổi, script Doconut đã sao chép, hành động thanh công cụ tùy chỉnh, callback của viewer và endpoint mở tài liệu.
  4. Bảo quản các tệp .lic hiện tại và bí mật triển khai bên ngoài hệ thống kiểm soát mã nguồn.
  5. Ghi lại một tập hợp đại diện các tài liệu PDF, Office, hình ảnh, CAD, email, DICOM, có thể tìm kiếm, được bảo vệ bằng mật khẩu và có chú thích.
  6. Ghi lại thời gian chờ phiên hiện tại, hành vi bảo mật, phông chữ và cài đặt nền tảng.

Di chuyển một môi trường trước khi thay đổi môi trường sản xuất. Tích hợp hiện tại thay đổi vòng đời dịch vụ, định tuyến yêu cầu, quyền sở hữu phiên, việc cung cấp tài nguyên cho khách hàng, và — nếu bạn chạy một farm — cách các trang tiếp cận trình duyệt.

1. Không gian tên: hầu hết mọi thứ được chuyển về gốc

Các kiểu cấu hình đã được phân tán qua bốn không gian tên. Bây giờ chúng đều nằm trong Doconut.

TrướcBây giờ
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;không thay đổi
using Doconut.Middleware;không thay đổi

Tên kiểu không thay đổi: WordConfig, PdfConfig, ExcelConfig, CssConfig, ScriptConfig, CloudUploadConfig, AzureConfig, CDNConfig, FileShareConfig và các phần còn lại vẫn tồn tại. Trong hầu hết các tệp, toàn bộ chỉnh sửa chỉ là xóa hai dòng using.

Doconut.Configs.Editor (BaseConfigEditor, PdfConfigEditor) đã bị loại bỏ và không có bản thay thế trong gói này. Nếu ứng dụng của bạn tham chiếu đến các kiểu đó, hãy lên kế hoạch phần này riêng và không coi nó là một phần của quá trình di chuyển này.

2. Tương thích gói và giấy phép

Thay thế hoặc cập nhật gói lõi một cách có chủ đích; không dựa vào ID gói giống hệt để chọn API mới. Lệnh mặc định sẽ cài đặt phiên bản ổn định mới nhất:

bash
dotnet add package Doconut.NETStandard

Để thực hiện di chuyển có thể tái tạo tới bản phát hành đã được kiểm toán bởi hướng dẫn này, hãy truyền phiên bản như một tùy chọn riêng:

bash
dotnet add package Doconut.NETStandard --version 26.8.0

Giữ mọi plugin Doconut ở cùng phiên bản với gói lõi — Doconut.NETStandard.Converter và Doconut.NETStandard.Dicom. Tích hợp hiện tại tải giấy phép một lần trong AddDoconut(), sử dụng thứ tự ưu tiên sau:

text
LicenseStream > LicenseContent > LicensePath > automatic discovery

Khám phá tự động sẽ tìm các tệp Doconut.Viewer.lic và các tệp đi kèm Doconut.Viewer.<Capability>.lic. Các lời gọi tĩnh trước đây Viewer.DoconutLicense(...) và Viewer.SetLicensePlugin(...) không còn là cơ chế khởi động hiện tại, và cũng không phải là List<string> các đường dẫn giấy phép mà hàm khởi tạo cũ của Viewer chấp nhận. Di chuyển giấy phép vào DoconutOptions, giữ các tệp đi kèm cùng nhau khi sử dụng khám phá tự động, khởi động lại sau khi thay đổi giấy phép, và xác minh các khả năng thông qua IDoconutLicenseService.

Không giả định rằng sự hiện diện của một giấy phép plugin cũ chứng minh quyền sử dụng cho bản dựng plugin hiện tại. Hãy kiểm tra Viewer, Search, Annotation, Converter và DICOM riêng biệt với các artefact phát hành đã được phê duyệt.

3. Khởi động và tiêm phụ thuộc

Trước đây, viewer được tạo cho mỗi yêu cầu và các tùy chọn được truyền vào middleware:

csharp
// Tích hợp trước — chỉ để so sánh; không biên dịch đoạn này với SDK hiện tại.
var viewer = new Viewer(_cache, _accessor);
// …
appBranch.UseDoconut(new DoconutOptions { UnSafeMode = false, ShowDoconutInfo = false });

Tích hợp hiện tại đăng ký Doconut một lần và nhận Viewer từ tiêm phụ thuộc:

csharp
builder.Services.AddDoconut(options =>
{
    options.UnsafeMode      = false;   // lưu ý thay đổi chính tả: UnSafeMode → UnsafeMode
    options.ShowDoconutInfo = false;
    options.LicensePath     = "Doconut.Viewer.lic";
});
builder.Services.AddDistributedMemoryCache(); // trạng thái phiên cần một bộ nhớ đệm (MVC/Razor Pages đã thêm sẵn)
builder.Services.AddSession();

app.UseSession();
app.UseDoconutResources();
app.UseDoconut();

Viewer là một dịch vụ tạm thời. Trình quản lý phiên tài liệu và bộ nhớ đệm của nó sở hữu trạng thái tài liệu lâu dài hơn, không phải thể hiện Viewer được tiêm cụ thể.

Ba điều cần lưu ý:

  • new Viewer(cache, accessor) đã bị loại bỏ. Tiêm Doconut.Viewer vào controller của bạn, hoặc dùng @inject Doconut.Viewer Viewer trong Razor view.
  • UseDoconutResources() thay thế việc tự tay gắn middleware app.UseMiddleware<EmbeddedResourceMiddleware>(), và phải chạy trước nhánh tài liệu.
  • UnSafeMode → UnsafeMode. Đây là một thay đổi một ký tự mà trình biên dịch sẽ phát hiện.

Khi UnsafeMode là false SDK sẽ xác thực token phiên so với yêu cầu gốc, vì vậy AddSession() / UseSession() vẫn phải có trong pipeline, và UseSession() phải được gọi trước nhánh.

Các phương thức không còn tồn tại

TrướcHiện tại
viewer.OpenDocument(path, config, options)await viewer.OpenDocumentAsync(path, config, options)
viewer.InitCache()đã loại bỏ — không có gì cần khởi động bằng tay; xóa lời gọi và bất kỳ cờ “đã khởi tạo?” nào xung quanh
viewer.ExportToPng(sharedPath)xem §7
viewer.ExportToCloud(cloudConfig)xem §7
using var v = new Viewer(...); v.CloseDocument(t)viewer.CloseDocument(token) trên thể hiện đã tiêm

4. Middleware và định tuyến tài nguyên

UseDoconut() hiện không nhận bất kỳ đối số nào. Hình dạng nhánh MapWhen tự nó không cần thay đổi — chỉ middleware bên trong nó:

csharp
app.UseDoconutResources();   // TRƯỚC nhánh

app.MapWhen(
    ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
    branch => branch.UseDoconut());

Trong pipeline hiện tại:

  1. gọi UseSession() trước Doconut khi bảo mật phiên được bật;
  2. gọi UseDoconutResources() trước UseDoconut();
  3. giữ ResourcesPath, các URL tài nguyên được tạo và ResPath của client đồng bộ;
  4. giữ nhánh bạn map và BasePath của client đồng bộ.

MiddlewarePath là cấu hình đã được xác thực; nó không tự tạo một nhánh ASP.NET Core.

5. Xây dựng và vòng đời Viewer

Xóa các bộ nhớ đệm do ứng dụng sở hữu của các đối tượng Viewer. Không còn gì đáng giữ lại trong một Viewer: nó không chứa trạng thái tài liệu, và bộ nhớ đệm phiên sở hữu mọi thứ tồn tại lâu hơn một yêu cầu. Tiêm nó vào một endpoint, trang Razor, controller, hoặc dịch vụ ứng dụng có phạm vi:

csharp
app.MapPost("/api/open", async (Viewer viewer) =>
{
    var token = await viewer.OpenDocumentAsync("wwwroot/files/Sample.pdf");
    return Results.Ok(new { token });
});

Token được trả về xác định một phiên tài liệu phía máy chủ. Xử lý nó như một chứng chỉ mang: không ghi log, không lưu trữ, và không đưa vào phân tích.

6. Mở và đóng tài liệu

Thay thế OpenDocument(...) đồng bộ bằng OpenDocumentAsync(...):

csharp
// Tích hợp hiện tại: Viewer được lấy từ DI và việc mở tài liệu là bất đồng bộ.
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { AllowSearch = true });

Các overload hiện tại chấp nhận đường dẫn tệp hoặc stream, một cấu hình định dạng tùy chọn, DocOptions tùy chọn, và một token hủy. Đóng phiên máy chủ một cách rõ ràng khi trình duyệt không còn cần nữa:

csharp
viewer.CloseDocument(token);

Xóa mọi lời gọi InitCache() và cờ bảo vệ nó — không có gì cần khởi động thủ công. Không tái sử dụng token được tạo bởi thư viện trước sau khi chuyển đổi: mở lại mỗi tài liệu thông qua API hiện tại.

7. Web farm → distributed: thay đổi lớn nhất

UseDoconutWebFarm và WebFarmOptions không còn tồn tại nữa. Nếu ứng dụng của bạn gọi chúng, phần này là bản nâng cấp của bạn; nếu không, bỏ qua tới §8.

Trước đây một middleware làm mọi việc: nó phục vụ các hình ảnh đã được render trước từ một thư mục chia sẻ, và được truy vấn liên tục trong khi một node khác vẫn đang ghi chúng.

csharp
// Tích hợp trước — một lời gọi, phối hợp ngầm qua hệ thống tệp.
appBranch.UseDoconutWebFarm(new WebFarmOptions
{
    Path                = Path.Combine(env.WebRootPath, "webfarm"),
    PageWaitTimeSeconds = 180,
    StartWaitFromPage   = 5,
});

Công việc tương tự hiện được chia thành hai nửa rõ ràng. Bên ghi — node mở tài liệu sẽ xuất toàn bộ bộ artefact (các trang, thông tin tài liệu, chỉ mục tìm kiếm, siêu dữ liệu) vào thư mục chia sẻ:

csharp
var result = await _publisher.PublishAsync(          // DistributedDocumentPublisher, được tiêm từ DI
    pathToFile,
    new FileShareConfig
    {
        Location              = CloudLocation.FileShare,
        RootPath              = @"\\fileserver\doconut",   // cùng thư mục bạn đang dùng hiện nay
        UsePerTokenSubfolders = true,
    },
    config,
    documentOptions,
    new DistributedDocumentPublishOptions
    {
        CleanUpStagingDirectory = true,
        FirstPagePriority       = true,
    });

return Content(result.Token);

Bên đọc — bất kỳ node nào cũng phục vụ từ thư mục chia sẻ:

csharp
app.MapWhen(
    ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
    branch => branch.UseDoconutCloud<FileShareCloudHandler>(options =>
    {
        options.Location          = CloudLocation.FileShare;
        options.CloudUploadConfig = /* CẤU HÌNH FileShareConfig GIỐNG NHƯ TRÊN */;
    }, "/"));
TrướcHiện tại
WebFarmOptions.PathFileShareConfig.RootPath
PageWaitTimeSeconds / StartWaitFromPageđã bỏ — thay thế bằng FirstPagePriority ở phía ghi cộng với FileShareConfig.ReadReadyPollMs ở phía đọc
viewer.OpenDocument(...) then viewer.ExportToPng(share)một lời gọi PublishAsync(...)
DocOptions.IsWebfarm / WebfarmPathvẫn còn, viết là IsWebFarm / WebFarmPath — nhưng không cần trên đường dẫn xuất bản

Topology của bạn không thay đổi. Đặt RootPath vào cùng một UNC share và mọi node sẽ tiếp tục hoạt động như hiện tại. Điều thay đổi là việc xuất bản trở thành một thao tác bạn gọi, thay vì là hiệu ứng phụ của việc render.

Cả hai nửa phải thống nhất. Nếu RootPath hoặc UsePerTokenSubfolders khác nhau giữa publisher và handler, node còn lại sẽ trả về 404. Xây dựng cấu hình trong một helper và gọi nó từ cả hai phía.

PageWaitTimeSeconds = 180 có nghĩa là "khóa tối đa ba phút chờ trang xuất hiện". Thay thế là rõ ràng: với FirstPagePriority = true, trang 1 có thể phục vụ ngay lập tức và các trang sau sẽ trả HTTP 202 Accepted cho tới khi được ghi. Viewer tích hợp sẽ tự động thử lại khi retryOn409 được bật. Một client không thử lại sẽ hiển thị các ô ảnh bị hỏng cho các trang vẫn đang render.

Bố cục đầy đủ, bao gồm xuất bản nền và vé truy cập, được mô tả trong Triển khai phân tán.

8. Chuyển đổi là một plugin, và nhỏ hơn nhiều

Đăng ký plugin, sau đó tiêm (inject) facade DocumentConverter:

csharp
builder.Services.AddDoconut(o => o.AddPlugin<ConverterPlugin>());
csharp
// Tích hợp trước đây
var converter = viewer.Converter.GetConverter();
var config    = new WordConfigConverter { TargetFormat = WordConfigConverter.EnTargetFormat.PDF };
var result    = converter.Convert(stream, SourceFormatConverter.DOCX, config);

// Tích hợp hiện tại
var result = await _converter.ConvertAsync(stream, ".docx", ConversionTarget.Pdf, null, ct);

Những gì nó thay thế:

  • SourceFormatConverter — đã bỏ. Truyền phần mở rộng tệp dưới dạng chuỗi, bao gồm dấu chấm.
  • Các kiểu *ConfigConverter theo từng họ (WordConfigConverter, ExcelConfigConverter, …), mỗi loại có một enum EnTargetFormat lồng nhau — đã bỏ. Bây giờ có một enum ConversionTarget cho mỗi họ.
  • viewer.Converter.GetConverter() — đã bỏ. Tiêm Doconut.DocumentConverter.

ConvertAsync trả về một stream có thể seek, vì vậy return File(result, mime, name) hoạt động trực tiếp — việc sao chép MemoryStream mà mã cũ cần không còn cần thiết. Trong mẫu được cung cấp, điều này đã xóa một switch mở rộng với 68 trường hợp và mười controller gần như giống nhau.

Xem Plugin Chuyển Đổi để biết toàn bộ tính năng.

9. Nhà cung cấp đám mây

UseDoconutCloud đã trở thành generic. Nhà cung cấp là đối số kiểu thay vì một giá trị Location được chuyển đổi bên trong middleware:

csharp
// Tích hợp trước đây
appBranch.UseDoconutCloud(new CloudOptions { Location = CloudLocation.CDN, ... });

// Tích hợp hiện tại
branch.UseDoconutCloud<CDNCloudHandler>(options =>
{
    options.Location          = CloudLocation.CDN;
    options.CloudUploadConfig = new CDNConfig { DoconutCdnUrl = "..." };
}, "/");

Các lớp cấu hình không thay đổi ngoại trừ không gian tên (Doconut.Configs.Cloud → Doconut.Clouds): AzureConfig, AmazonConfig, GoogleCloudConfig, DropBoxConfig, RedisConfig, CDNConfig, FTPConfig, cộng với FileShareConfig mới. Các handler được đặt tên <Provider>CloudHandler.

Handler CDN là chỉ đọc — nó phục vụ những gì đã có trên CDN; nó không tải lên.

10. Các đối tượng cấu hình đã đổi tên

TrướcHiện tại
DoconutOptions.UnSafeModeUnsafeMode
DocOptions.IsWebfarmIsWebFarm
DocOptions.WebfarmPathWebFarmPath
DocOptions.ImageResolutionvẫn tồn tại nhưng đã lỗi thời — đặt độ phân giải trên cấu hình định dạng thay vì

DocOptions cũng thêm IsSecured.

API hiện tại cũng tách biệt các mối quan tâm chặt chẽ hơn so với phiên bản trước, vì vậy hãy kiểm tra mỗi thiết lập nằm trên đối tượng hiện đang sở hữu nó:

Mối quan tâmKiểu hiện tại
Đường dẫn middleware, giấy phép, đăng ký pluginDoconutOptions
Mật khẩu, thời gian chờ, bảo mật, watermarkDocOptions
Kết xuất định dạng và DPIPdfConfig, WordConfig, ExcelConfig, và các kiểu BaseConfig khác
Mặc định widget trình duyệtViewerConfig hoặc các tùy chọn JavaScript tương đương
CSS và script được tạoCssConfig và ScriptConfig
Lưu trữ chia sẻ và nhà cung cấp đám mâyFileShareConfig và các cấu hình Doconut.Clouds khác

Không nên tiếp tục sử dụng DocOptions.ImageResolution làm điều khiển render. Nó đã lỗi thời; hãy đặt BaseConfig.ImageResolution trên cấu hình riêng cho định dạng. Xem lại tất cả các mặc định thay vì giả định một cấu hình trước đây có cùng hành vi.

11. Trình xem phía client — hai thay đổi gây lỗi MỘT CÁCH IM LẶNG

Cả hai thay đổi này đều để máy chủ hoạt động hoàn hảo. Tài liệu của bạn được render, trang hiển thị đúng, và không có gì xuất hiện trong console của trình duyệt. Hãy đọc phần này ngay cả khi mã C# của bạn biên dịch thành công ngay lần đầu.

Các callback của Viewer hiện là tùy chọn, không còn là hàm toàn cục

Trình xem trước đây gọi các handler của bạn bằng tên, suy ra tên hàm toàn cục từ id của container. Việc khai báo function ctlDoc_OnViewerReady() trên một trang có <div id="div_ctlDoc"> đã đủ. Trình xem hiện tại nhận các callback rõ ràng trong đối tượng options và không còn tìm kiếm các hàm toàn cục nữa:

javascript
objctlDoc = $("#div_ctlDoc").docViewer({
    // ... các tùy chọn hiện có của bạn ...
    onViewerBusy:     ctlDoc_OnViewerBusy,      // đã được tìm bằng tên
    onViewerReady:    ctlDoc_OnViewerReady,     // đã được tìm bằng tên
    onCopy:           ctlDoc_Copy,              // là ctlDoc_Copy(text)
    onAutoLoadStatus: ctlDoc_AutoLoadStatus     // là ctlDoc_AutoLoadStatus(page)
});

Tại sao điều này lại tệ: lời gọi cũ được bao bọc trong một catch rỗng, khiến mọi lỗi bị nuốt. Bây giờ các hàm của bạn đơn giản không bao giờ chạy và không có gì báo cáo lỗi. Triệu chứng thường gặp là biểu tượng quay đang bận không bao giờ dừng — vì hàm ẩn nó là ctlDoc_OnViewerReady. Tài liệu phía sau vẫn ổn.

Danh sách đầy đủ các tùy chọn là onPageLoading, onPageLoaded, onThumbnailClicked, onPageClicked, onDoubleClick, onViewerBusy, onViewerReady, onViewerError, onCopy, onAnnSaved, onAnnSaveError, onAnnLoaded, onAnnClosed, onAutoLoadStatus, onThumbsShown, và onError. Không có callback cho việc nhấp liên kết: việc xử lý hyperlink đã được tích hợp, được điều khiển bởi showHyperlinks.

ResPath phải trỏ tới tiền tố tài nguyên

javascript
ResPath: '',                      // BEFORE — tài nguyên được lấy từ gốc ứng dụng
ResPath: 'doconut-res/images',    // NOW    — tiền tố mà UseDoconutResources() gắn

Nếu bạn đã thay đổi tiền tố qua DoconutOptions.ResourcesPath, hãy sử dụng giá trị đó thay thế.

12. Thanh công cụ Viewer, Tìm kiếm và Ghi chú

Không nên di chuyển từng script cũ một. Các ứng dụng tham chiếu hiện tại tạo thành một gói trang hoàn chỉnh:

  1. phát ra CSS của Viewer và CSS có giấy phép cho Tìm kiếm/Ghi chú bằng ReferenceCss;
  2. hiển thị thanh công cụ Viewer thuộc sở hữu của ứng dụng;
  3. hiển thị searchBarMount, annBarMount, và phần gắn Viewer cần thiết;
  4. phát ra script của Viewer và các mô-đun có giấy phép bằng ReferenceScripts;
  5. tải script trợ giúp thanh công cụ riêng của ứng dụng;
  6. khởi tạo một objViewer;
  7. khởi tạo các Ribbon Tìm kiếm và Ghi chú có giấy phép;
  8. gọi attach(objViewer) trên mỗi Ribbon;
  9. mở tài liệu và gọi objViewer.View(token).

Tìm kiếm và Ghi chú là các mô-đun được gắn vào cùng một Viewer, không phải các thanh công cụ độc lập. Thanh công cụ chính thuộc về ứng dụng chủ; các Ribbon Tìm kiếm và Ghi chú được nhúng, là các tài nguyên được kiểm soát theo khả năng.

Chỉ xóa các tệp được sao chép thủ công như documentLinks.js và docViewer.UI.js sau khi trang hiện tại hoạt động với các tài nguyên được phát ra bởi ReferenceCss và ReferenceScripts.

13. Đăng ký Plugin

Phương thức cấp phép plugin tĩnh không đăng ký các plugin hiện tại. Cài đặt và đăng ký mỗi gói đã phát hành một cách rõ ràng:

csharp
builder.Services.AddDoconut(options =>
{
    options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
    options.AddPlugin<Doconut.Plugins.Dicom.DicomPlugin>();
});

AddDoconut() xác thực các khả năng plugin đã đăng ký khi khởi động. Converter và DICOM là các plugin .NET Standard đã phát hành. Tìm kiếm và Ghi chú thông thường là các tính năng có giấy phép tích hợp sẵn, không phải các gói AddPlugin<TPlugin>().

14. Phiên và bảo mật tài liệu

Tích hợp hiện tại gắn tài liệu với các token không trong suốt và các phiên được lưu trong bộ nhớ đệm. Với mặc định UnsafeMode = false, UseDoconut() thêm bảo mật truy cập tài liệu và máy chủ phải cấu hình phiên ASP.NET:

csharp
builder.Services.AddDistributedMemoryCache(); // trạng thái phiên cần một bộ nhớ đệm (MVC/Razor Pages đã thêm sẵn một bộ)
builder.Services.AddSession();
app.UseSession();

Giữ DocOptions.IsSecured = true trừ khi một thiết kế đã được xem xét yêu cầu ngược lại. Không bao giờ sử dụng UnsafeMode = true như một cách tắt ngắn cho việc di chuyển trên một nút duy nhất. Kiểm tra các yêu cầu không có token, token sai định dạng, token đã hết hạn, và token từ một phiên trình duyệt khác.

Trong một môi trường farm, yêu cầu trang có thể tới một nút chưa từng nhận được yêu cầu mở, vì vậy kiểm tra theo phiên sẽ từ chối nó. Đó là trường hợp duy nhất mà UnsafeMode = true là đúng — và nó phải được kết hợp với vé truy cập có chữ ký thông qua AddDoconutDistributedDocumentSecurity, không được sử dụng riêng lẻ. Xem Triển khai phân tán.

Ghi chú đặt tên

Trong tất cả các framework, lớp là Viewer. Nếu bạn gặp DocumentViewer trong các đoạn mã cũ hoặc bài viết của bên thứ ba, kiểu đó chưa từng tồn tại trong SDK.

15. Thứ tự công việc đề xuất

  1. Xác nhận framework chủ có thể tiêu thụ netstandard2.1. Nếu không, dừng lại.
  2. Nâng cấp gói lên 26.8.0 và biên dịch. Xử lý các lỗi biên dịch — phần lớn là các dòng using trong §1.
  3. Di chuyển khởi động tới AddDoconut() và các lời gọi middleware tới thứ tự mới của chúng (§3, §4).
  4. Tiêm Viewer vào nơi bạn đã tạo nó, biến OpenDocument thành async, và xóa InitCache() (§5, §6).
  5. Nếu bạn sử dụng web farm, thực hiện §7 — phần duy nhất là thiết kế lại thay vì đổi tên.
  6. Nếu bạn chuyển đổi tài liệu, thực hiện §8.
  7. Thực hiện §11 — các thay đổi phía client. Đây là những thay đổi mà không tự hiển thị.
  8. Mở một tài liệu thực trong trình duyệt và quan sát biểu tượng đang tải. Một bản dựng màu xanh không chứng minh gì ở đây: giấy phép, đăng ký plugin, đường dẫn tài nguyên và các callback của viewer đều chỉ thất bại khi chạy. Đối với farm, xác minh rằng một tài liệu được xuất bản bởi một nút được máy khác phục vụ.

Kiểm tra việc di chuyển

Ít nhất, hãy xác minh:

  • khởi động ứng dụng với giấy phép sản xuất và mọi plugin đã đăng ký;
  • CSS/script của Viewer và tất cả các yêu cầu hình ảnh trang dưới các đường dẫn đã chọn;
  • mở tài liệu, điều hướng, phóng to/thu nhỏ, hình thu nhỏ, in và đóng rõ ràng;
  • tìm kiếm trên tài liệu có văn bản và trạng thái không thể tìm kiếm của tệp chỉ có hình ảnh;
  • tải, lưu, xuất chú thích và kiểm soát khả năng;
  • khám phá mục tiêu chuyển đổi, đầu ra, tải xuống và trạng thái watermark;
  • các trang DICOM, khung và hoạt ảnh; siêu dữ liệu kỹ thuật không có sẵn trong gói này;
  • tài liệu được bảo vệ bằng mật khẩu, phông chữ tùy chỉnh, văn bản không phải Latin và thời gian chờ đã cấu hình;
  • từ chối token giữa các phiên và hành vi phiên đã hết hạn;
  • đối với một farm: xuất bản trên một nút, yêu cầu một trang trễ từ nút khác, và xác nhận Viewer sẽ thử lại các phản hồi 202 thay vì hiển thị các ô bị hỏng;
  • di động, chế độ tối và đường dẫn reverse‑proxy sản xuất.

Kế hoạch quay lại

Giữ nguyên artifact triển khai trước đó, các gói tương ứng, tệp giấy phép và các tài nguyên trình duyệt đã sao chép cùng nhau. Một quá trình quay lại an toàn sẽ chuyển đổi toàn bộ thế hệ ứng dụng; nó không trộn lẫn máy chủ thế hệ trước với các script hiện tại, hoặc máy chủ hiện tại với các vị trí gọi new Viewer(...).

Trước khi chuyển đổi, hãy ghi lại:

  • khe triển khai hoặc artifact được sử dụng để quay lại;
  • tác động của lưu trữ chia sẻ, nếu có — các artifact được xuất bản bởi 26.8.0 không được middleware web‑farm trước đó tiêu thụ;
  • cách các phiên tài liệu đang hoạt động sẽ bị vô hiệu hoá;
  • bản kiểm tra sức khỏe và tài liệu smoke được sử dụng để quyết định quay lại;
  • ai có thể khôi phục bộ gói và cấu hình trước đó.

Tài liệu kế thừa

Sổ tay trước đây đã được dịch vẫn khả dụng tại Cài đặt .NET Standard kế thừa. Cổng tích hợp trước đây giải thích các tín hiệu nhận dạng tương tự và liên kết trở lại hướng dẫn di chuyển này.

Giữ URL lịch sử trong dấu trang và phiếu hỗ trợ trong khi các cài đặt netstandard2.0 vẫn còn tồn tại. Nó ghi lại một thế hệ khác và không được chuyển hướng tới API hiện tại.

Trang này có hữu ích không?