.NET Standard 2.1 로 마이그레이션
기존 Doconut.NETStandard 애플리케이션을 26.7.0에서 26.8.0으로 이동
Doconut은 두 가지 별도 .NET Standard 통합을 제공합니다. 동일한 Doconut.NETStandard 패키지 이름을 사용하므로, 패키지, 시작, 라이선스 또는 브라우저 리소스를 변경하기 전에 버전과 애플리케이션 내 API를 확인하여 세대를 식별하십시오.
버전은 갈림길이다
두 세대는 동일한 패키지 ID로 배포됩니다. 버전만이 두 버전을 구분합니다:
| 버전 | 대상 | API |
|---|---|---|
| 26.7.0 이하 | netstandard2.0 | 이전 API |
| 26.8.0 이상 | netstandard2.1 | 현재 API |
버전 번호를 올리는 것이 업그레이드입니다. 별도의 설치 패키지는 없으며 호환성 쉼이 존재하지 않습니다 — 26.8.0은 다른 API 표면을 가집니다. 버전 업 후 컴파일 오류가 발생할 수 있으며, 이 가이드의 나머지는 그 오류 목록입니다.
어떤 통합을 사용하고 있나요?
| 프로젝트에 포함된 경우… | 세대 |
|---|---|
new Viewer(_cache, _accessor, ...) | 이전 |
viewer.OpenDocument(...) (동기) | 이전 |
viewer.InitCache() | 이전 |
UseDoconut(new DoconutOptions { ... }) | 이전 |
UseDoconutWebFarm(...) / WebFarmOptions | 이전 |
Viewer.DoconutLicense(...) 또는 Viewer.SetLicensePlugin(...) | 이전 |
viewer.Converter.GetConverter() | 이전 |
using Doconut.Configs; / using Doconut.Models; | 이전 |
수동으로 복사한 docViewer.js, documentLinks.js, 또는 docViewer.UI.js | 이전 |
builder.Services.AddDoconut(...) | 현재 |
app.UseDoconutResources()와 app.UseDoconut()를 인수 없이 사용 | 현재 |
DI(의존성 주입)으로 제공되는 Viewer | 현재 |
await viewer.OpenDocumentAsync(...) | 현재 |
두 열이 동일 애플리케이션에 모두 나타난다면 마이그레이션이 완전하지 않은 것입니다. 한 세대의 리소스나 미들웨어를 통해 다른 세대의 문서 토큰을 보내지 마십시오.
먼저 호스트 프레임워크를 확인하세요
이는 선호도가 아니라 강제 조건입니다. 현재 패키지는 netstandard2.1을 대상으로 합니다:
| 호스트 | 26.8.0 사용 가능 여부 |
|---|---|
| .NET Core 3.0 이상 (including .NET 5/6/7/8) | 예 |
| .NET Framework, 모든 버전 | 아니오 |
.NET Framework는 netstandard2.1 라이브러리를 참조할 수 없습니다. 애플리케이션이 .NET Framework에서 실행된다면 여기서 중단하고 대신 Doconut.NETFramework 패키지를 사용하십시오; 26.9.0부터는 .NET Framework 4.7.2가 필요합니다. 이 릴리스의 두 레퍼런스 애플리케이션은 net8.0을 대상으로 합니다.
마이그레이션 전에 해야 할 일
- 기존 애플리케이션의 브랜치를 만들고 배포 가능한 백업을 생성합니다.
- 핵심 및 플러그인 패키지 버전을 정확히 기록합니다.
- 모든
new Viewer(...)호출,InitCache()호출, 라이선스 로드 호출,UseDoconutWebFarm매핑, 변환 컨트롤러, 복사된 Doconut 스크립트, 사용자 정의 툴바 액션, 뷰어 콜백, 문서 열기 엔드포인트를 조사합니다. - 현재
.lic파일과 배포 비밀을 소스 제어 외부에 보관합니다. - PDF, Office, 이미지, CAD, 이메일, DICOM, 검색 가능, 비밀번호 보호, 주석이 달린 문서들을 대표적으로 수집합니다.
- 기존 세션 타임아웃, 보안 동작, 폰트, 플랫폼 설정을 기록합니다.
프로덕션을 변경하기 전에 하나의 환경에서 먼저 마이그레이션하십시오. 현재 통합은 서비스 수명, 요청 라우팅, 세션 소유권, 클라이언트 리소스 전달 방식을 바꾸며, — 팜을 운영한다면 — 페이지가 브라우저에 도달하는 방식을 변경합니다.
1. 네임스페이스: 거의 모든 것이 루트로 이동
구성 타입들은 네 개의 네임스페이스에 흩어져 있었습니다. 이제 모두 Doconut에 위치합니다.
| 이전 | 현재 |
|---|---|
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; | 변경 없음 |
using Doconut.Middleware; | 변경 없음 |
타입 이름은 변경되지 않았습니다: WordConfig, PdfConfig, ExcelConfig, CssConfig, ScriptConfig, CloudUploadConfig, AzureConfig, CDNConfig, FileShareConfig 등은 그대로 존재합니다. 대부분의 파일에서는 두 개의 using 라인을 삭제하는 것이 전부입니다.
Doconut.Configs.Editor(BaseConfigEditor, PdfConfigEditor)는 제거되었으며 이 패키지에 대체가 없습니다. 애플리케이션이 해당 타입들을 참조하고 있다면 별도로 계획을 세우고 이번 마이그레이션의 일부로 취급하지 마십시오.
2. 패키지 및 라이선스 호환성
핵심 패키지를 의도적으로 교체하거나 업데이트하십시오; 새로운 API를 선택하기 위해 동일한 패키지 ID에 의존하지 마세요. 기본 명령은 최신 안정 버전을 설치합니다:
dotnet add package Doconut.NETStandard이 가이드에서 검증된 릴리스로 재현 가능한 마이그레이션을 위해 버전을 별도 옵션으로 전달하십시오:
dotnet add package Doconut.NETStandard --version 26.8.0모든 Doconut 플러그인을 핵심 패키지와 동일한 버전으로 유지하십시오 — Doconut.NETStandard.Converter 및 Doconut.NETStandard.Dicom. 현재 통합은 AddDoconut() 동안 라이선스를 한 번 로드하며, 다음 우선순위를 사용합니다:
LicenseStream > LicenseContent > LicensePath > automatic discovery자동 검색은 Doconut.Viewer.lic 및 해당하는 Doconut.Viewer.<Capability>.lic 파일을 찾습니다. 이전 정적 호출 Viewer.DoconutLicense(...)와 Viewer.SetLicensePlugin(...)은 현재 시작 메커니즘이 아니며, 이전 Viewer 생성자가 허용하던 라이선스 경로 List<string>도 마찬가지입니다. 라이선스를 DoconutOptions로 이동하고, 자동 검색을 사용할 때는 관련 파일을 함께 두며, 라이선스를 변경한 후에는 재시작하고, IDoconutLicenseService를 통해 기능을 확인하십시오.
오래된 플러그인 라이선스가 있다고 해서 현재 플러그인 빌드에 대한 권한이 있다고 가정하지 마세요. 승인된 릴리스 아티팩트를 사용하여 Viewer, Search, Annotation, Converter, 그리고 DICOM을 각각 별도로 테스트하십시오.
3. 시작 및 의존성 주입
이전에는 뷰어가 요청당 생성되고 옵션이 미들웨어에 전달되었습니다:
// 이전 통합 — 대비용만; 현재 SDK와 함께 컴파일하지 마세요.
var viewer = new Viewer(_cache, _accessor);
// …
appBranch.UseDoconut(new DoconutOptions { UnSafeMode = false, ShowDoconutInfo = false });현재 통합은 Doconut을 한 번 등록하고 의존성 주입을 통해 Viewer를 받습니다:
builder.Services.AddDoconut(options =>
{
options.UnsafeMode = false; // 철자 변경에 주의: UnSafeMode → UnsafeMode
options.ShowDoconutInfo = false;
options.LicensePath = "Doconut.Viewer.lic";
});
builder.Services.AddDistributedMemoryCache(); // 세션 상태에 캐시가 필요합니다 (MVC/Razor Pages는 이미 하나를 추가합니다)
builder.Services.AddSession();
app.UseSession();
app.UseDoconutResources();
app.UseDoconut();Viewer는 일시적인 서비스입니다. 문서 세션 관리자와 그 캐시는 장기적인 문서 상태를 소유하며, 특정 주입된 Viewer 인스턴스는 아닙니다.
전달해야 할 세 가지 사항:
new Viewer(cache, accessor)가 사라졌습니다. 컨트롤러에Doconut.Viewer를 주입하거나 Razor 뷰에서@inject Doconut.Viewer Viewer를 사용하십시오.- **
UseDoconutResources()**는 수동으로app.UseMiddleware<EmbeddedResourceMiddleware>()를 연결하던 방식을 대체하며, 문서 브랜치보다 먼저 실행되어야 합니다. UnSafeMode→UnsafeMode. 한 글자만 바뀐 이름으로, 컴파일러가 잡아냅니다.
UnsafeMode가 false이면 SDK가 세션 토큰을 원본 요청과 비교해 검증하므로, AddSession() / UseSession()은 파이프라인에 여전히 포함되어야 하며, 브랜치보다 먼저 UseSession()이 호출되어야 합니다.
더 이상 존재하지 않는 메서드
| 이전 | 현재 |
|---|---|
viewer.OpenDocument(path, config, options) | await viewer.OpenDocumentAsync(path, config, options) |
viewer.InitCache() | removed — 수동으로 초기화할 것이 없으므로 호출을 삭제하고 주변의 "이미 초기화했나요?" 플래그도 제거하십시오 |
viewer.ExportToPng(sharedPath) | §7 참조 |
viewer.ExportToCloud(cloudConfig) | §7 참조 |
using var v = new Viewer(...); v.CloseDocument(t) | viewer.CloseDocument(token)을 주입된 인스턴스에서 호출합니다 |
4. 미들웨어 및 리소스 라우팅
UseDoconut()은 이제 인수를 받지 않습니다. MapWhen 브랜치 형태 자체는 변경할 필요가 없으며, 내부 미들웨어만 교체하면 됩니다:
app.UseDoconutResources(); // BEFORE the branch
app.MapWhen(
ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
branch => branch.UseDoconut());현재 파이프라인에서는:
- 세션 보안이 활성화된 상태에서 Doconut보다 먼저
UseSession()을 호출합니다; UseDoconutResources()를UseDoconut()보다 먼저 호출합니다;ResourcesPath, 생성된 리소스 URL, 그리고 클라이언트ResPath를 일치시킵니다;- 매핑한 브랜치와 클라이언트
BasePath를 일치시킵니다.
MiddlewarePath는 검증된 구성이며, 자체적으로 ASP.NET Core 브랜치를 생성하지는 않습니다.
5. 뷰어 구성 및 수명
Application이 소유한 Viewer 객체 캐시를 제거합니다. Viewer에 보관할 가치가 남아 있는 것이 없습니다: 문서 상태를 전혀 보유하지 않으며, 세션 캐시가 요청보다 오래 지속되는 모든 것을 소유합니다. 이를 엔드포인트, Razor 페이지, 컨트롤러 또는 범위가 지정된 애플리케이션 서비스에 주입합니다:
app.MapPost("/api/open", async (Viewer viewer) =>
{
var token = await viewer.OpenDocumentAsync("wwwroot/files/Sample.pdf");
return Results.Ok(new { token });
});반환된 토큰은 서버 측 문서 세션을 식별합니다. 이를 베어러 자격 증명으로 취급하십시오: 로그에 기록하거나, 영구 저장하거나, 분석에 포함하지 마세요.
6. 문서 열기 및 닫기
동기식 OpenDocument(...)을 OpenDocumentAsync(...)로 교체합니다:
// 현재 통합: Viewer는 DI에서 제공되며 문서 열기가 비동기식입니다.
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { AllowSearch = true });현재 오버로드는 파일 경로나 스트림, 선택적 포맷 구성, 선택적 DocOptions, 그리고 취소 토큰을 허용합니다. 브라우저가 더 이상 필요로 하지 않을 때 서버 세션을 명시적으로 종료하십시오:
viewer.CloseDocument(token);InitCache() 호출 및 이를 보호하던 플래그를 모두 삭제합니다 — 수동으로 준비할 것이 없습니다. 전환 후 이전 라이브러리에서 발행된 토큰을 재사용하지 마세요: 현재 API를 통해 각 문서를 다시 엽니다.
7. 웹 팜 → 분산: 가장 큰 변화
UseDoconutWebFarm 및 WebFarmOptions는 더 이상 존재하지 않습니다. 애플리케이션에서 이를 호출한다면 이 섹션이 업그레이드 가이드이며, 호출하지 않는다면 §8로 건너뛰세요.
이전에는 하나의 미들웨어가 모든 작업을 수행했습니다: 공유 폴더에서 사전 렌더링된 이미지를 제공하고, 다른 노드가 아직 이미지를 쓰는 동안 폴링했습니다.
// 이전 통합 — 하나의 호출, 파일 시스템을 통한 암시적 조정.
appBranch.UseDoconutWebFarm(new WebFarmOptions
{
Path = Path.Combine(env.WebRootPath, "webfarm"),
PageWaitTimeSeconds = 180,
StartWaitFromPage = 5,
});동일한 작업이 이제 두 개의 명시적인 절반으로 나뉩니다. Write side — 문서를 여는 노드가 전체 아티팩트 세트(페이지, 문서 정보, 검색 인덱스, 메타데이터)를 공유에 게시합니다:
var result = await _publisher.PublishAsync( // DistributedDocumentPublisher, DI에서 주입됨
pathToFile,
new FileShareConfig
{
Location = CloudLocation.FileShare,
RootPath = @"\\fileserver\doconut", // 오늘 사용하는 동일한 폴더
UsePerTokenSubfolders = true,
},
config,
documentOptions,
new DistributedDocumentPublishOptions
{
CleanUpStagingDirectory = true,
FirstPagePriority = true,
});
return Content(result.Token);Read side — 모든 노드가 공유에서 서비스를 제공합니다:
app.MapWhen(
ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
branch => branch.UseDoconutCloud<FileShareCloudHandler>(options =>
{
options.Location = CloudLocation.FileShare;
options.CloudUploadConfig = /* 위와 동일한 FileShareConfig */;
}, "/"));| 이전 | 현재 |
|---|---|
WebFarmOptions.Path | FileShareConfig.RootPath |
PageWaitTimeSeconds / StartWaitFromPage | 삭제됨 — 쓰기 측에서는 FirstPagePriority 로, 읽기 측에서는 FileShareConfig.ReadReadyPollMs 로 대체됨 |
viewer.OpenDocument(...) then viewer.ExportToPng(share) | PublishAsync(...) 호출 하나 |
DocOptions.IsWebfarm / WebfarmPath | 여전히 존재하지만, IsWebFarm / WebFarmPath 로 표기됨 — 그러나 publish 경로에서는 필요 없음 |
토폴로지는 변경되지 않습니다. RootPath를 동일한 UNC 공유에 지정하면 모든 노드가 오늘과 같은 방식으로 계속 작동합니다. 변하는 점은 렌더링의 부수 효과가 아니라 호출하는 작업으로서 퍼블리싱이 이루어진다는 것입니다.
두 절반은 일치해야 합니다.
RootPath또는UsePerTokenSubfolders가 퍼블리셔와 핸들러 사이에서 다르면 다른 노드는 404를 반환합니다. 하나의 헬퍼에서 구성을 만들고 양쪽에서 호출하십시오.
PageWaitTimeSeconds = 180은 “페이지가 나타날 때까지 최대 3분까지 차단”을 의미했습니다. 이제는 명시적입니다: FirstPagePriority = true를 사용하면 1페이지는 즉시 제공되고 이후 페이지는 HTTP 202 Accepted 응답을 반환하며 작성될 때까지 대기합니다. 번들된 뷰어는 retryOn409가 설정된 경우 자동으로 재시도합니다. 재시도하지 않는 클라이언트는 아직 렌더링 중인 페이지에 대해 깨진 타일을 표시합니다.
전체 구성(백그라운드 퍼블리싱 및 액세스 티켓 포함)은 분산 배포 문서에 나와 있습니다.
8. 변환은 플러그인이며, 훨씬 작아졌습니다
플러그인을 등록한 뒤 DocumentConverter 파사드를 주입합니다:
builder.Services.AddDoconut(o => o.AddPlugin<ConverterPlugin>());// 이전 통합
var converter = viewer.Converter.GetConverter();
var config = new WordConfigConverter { TargetFormat = WordConfigConverter.EnTargetFormat.PDF };
var result = converter.Convert(stream, SourceFormatConverter.DOCX, config);
// 현재 통합
// 현재 통합
var result = await _converter.ConvertAsync(stream, ".docx", ConversionTarget.Pdf, null, ct);대체되는 내용:
SourceFormatConverter— 사라졌습니다. 파일 확장자를 문자열로 전달하세요, 점(.) 포함.- 가족별
*ConfigConverter타입 (WordConfigConverter,ExcelConfigConverter, …) 및 중첩된EnTargetFormat열거형 — 사라졌습니다. 이제 각 가족마다 하나의ConversionTarget열거형이 있습니다. viewer.Converter.GetConverter()— 사라졌습니다.Doconut.DocumentConverter를 주입하세요.
ConvertAsync는 탐색 가능한 스트림을 반환하므로 return File(result, mime, name)을 바로 사용할 수 있습니다 — 이전 코드에서 필요했던 MemoryStream 복사는 불필요합니다. 제공된 샘플에서는 68가지 확장자 스위치를 삭제하고 거의 동일한 10개의 컨트롤러를 없앴습니다.
전체 기능을 보려면 컨버터 플러그인을 참조하십시오.
9. 클라우드 제공자
UseDoconutCloud이 제네릭으로 바뀌었습니다. 제공자는 미들웨어 내부에서 Location 값을 전환하는 대신 타입 인자로 지정됩니다:
// 이전 통합
appBranch.UseDoconutCloud(new CloudOptions { Location = CloudLocation.CDN, ... });
// 현재 통합
branch.UseDoconutCloud<CDNCloudHandler>(options =>
{
options.Location = CloudLocation.CDN;
options.CloudUploadConfig = new CDNConfig { DoconutCdnUrl = "..." };
}, "/");구성 클래스는 네임스페이스(Doconut.Configs.Cloud → Doconut.Clouds)를 제외하고는 변경되지 않았습니다: AzureConfig, AmazonConfig, GoogleCloudConfig, DropBoxConfig, RedisConfig, CDNConfig, FTPConfig와 새로 추가된 FileShareConfig. 핸들러 이름은 <Provider>CloudHandler 형식입니다.
CDN 핸들러는 읽기 전용이며 — CDN에 이미 존재하는 내용을 제공할 뿐, 업로드는 하지 않습니다.
10. 이름이 변경된 구성 객체
| 이전 | 현재 |
|---|---|
DoconutOptions.UnSafeMode | UnsafeMode |
DocOptions.IsWebfarm | IsWebFarm |
DocOptions.WebfarmPath | WebFarmPath |
DocOptions.ImageResolution | 여전히 존재하지만 obsolete — 형식 구성에서 해상도를 설정하세요 |
DocOptions에 IsSecured가 추가되었습니다.
현재 API는 이전보다 관심사를 더 엄격히 분리하므로, 각 설정이 이제 소유하고 있는 객체에 있는지 확인하십시오:
| 관심사 | 현재 타입 |
|---|---|
| 미들웨어 경로, 라이선스, 플러그인 등록 | DoconutOptions |
| 비밀번호, 타임아웃, 보안, 워터마크 | DocOptions |
| 형식 렌더링 및 DPI | PdfConfig, WordConfig, ExcelConfig, 및 기타 BaseConfig 타입 |
| 브라우저 위젯 기본값 | ViewerConfig 또는 동등한 JavaScript 옵션 |
| 생성된 CSS 및 스크립트 | CssConfig와 ScriptConfig |
| 공유 스토리지 및 클라우드 제공자 | FileShareConfig와 기타 Doconut.Clouds 구성 |
DocOptions.ImageResolution을 렌더링 제어로 사용하지 마세요. 이는 더 이상 사용되지 않으며, 형식별 구성에서 BaseConfig.ImageResolution을 설정해야 합니다. 이전 구성과 동일한 동작을 가정하지 말고 모든 기본값을 검토하십시오.
11. 클라이언트 측 뷰어 — 조용히 실패하는 두 가지 변경 사항
이 두 가지 모두 서버는 정상적으로 동작합니다. 문서는 렌더링되고 페이지도 정상이며 브라우저 콘솔에 아무런 메시지도 나타나지 않습니다. C#이 처음 컴파일될 때라도 이 섹션을 읽어보세요.
뷰어 콜백이 이제 옵션이며, 전역 함수가 아닙니다
이전 뷰어는 컨테이너 ID에서 파생된 전역 함수 이름으로 이름으로 핸들러를 호출했습니다. <div id="div_ctlDoc">가 있는 페이지에 function ctlDoc_OnViewerReady()를 선언하면 충분했습니다. 현재 뷰어는 옵션 객체에 명시적인 콜백을 전달받으며, 더 이상 전역 함수를 찾지 않습니다:
objctlDoc = $("#div_ctlDoc").docViewer({
// ... your existing options ...
onViewerBusy: ctlDoc_OnViewerBusy, // 이름으로 찾았습니다
onViewerReady: ctlDoc_OnViewerReady, // 이름으로 찾았습니다
onCopy: ctlDoc_Copy, // ctlDoc_Copy(text)와 동일
onAutoLoadStatus: ctlDoc_AutoLoadStatus // ctlDoc_AutoLoadStatus(page)와 동일
});왜 문제가 되는가: 이전 호출은 빈 catch로 감싸져 모든 오류를 무시했습니다. 이제 함수가 실행되지 않을 뿐 오류가 보고되지 않습니다. 일반적인 증상은 멈추지 않는 로딩 스피너이며, 이는 숨기는 함수가 ctlDoc_OnViewerReady였기 때문입니다. 문서 자체는 정상입니다.
전체 옵션 목록은 onPageLoading, onPageLoaded, onThumbnailClicked, onPageClicked, onDoubleClick, onViewerBusy, onViewerReady, onViewerError, onCopy, onAnnSaved, onAnnSaveError, onAnnLoaded, onAnnClosed, onAutoLoadStatus, onThumbsShown, onError 입니다. 링크 클릭 콜백은 없습니다: 하이퍼링크 처리는 내장되어 있으며 showHyperlinks에 의해 제어됩니다.
ResPath는 리소스 접두사에 지정되어야 합니다
ResPath: '', // BEFORE — 리소스가 애플리케이션 루트에서 제공되었습니다
ResPath: 'doconut-res/images', // NOW — UseDoconutResources()가 마운트하는 접두사DoconutOptions.ResourcesPath를 통해 접두사를 변경한 경우, 해당 값을 대신 사용하십시오.
12. 뷰어 툴바, 검색 및 주석
오래된 스크립트를 하나씩 마이그레이션하지 마십시오. 현재 레퍼런스 애플리케이션은 하나의 완전한 페이지 패키지를 구성합니다:
ReferenceCss를 사용하여 Viewer CSS와 라이선스된 Search/Annotation CSS를 출력합니다;- 애플리케이션이 소유한 Viewer 툴바를 렌더링합니다;
searchBarMount,annBarMount및 필요한 Viewer 마운트를 렌더링합니다;ReferenceScripts를 사용하여 Viewer 및 라이선스된 모듈 스크립트를 출력합니다;- 애플리케이션 자체 툴바 헬퍼 스크립트를 로드합니다;
objViewer하나를 초기화합니다;- 라이선스된 Search 및 Annotation 리본을 초기화합니다;
- 각 리본에서
attach(objViewer)를 호출합니다; - 문서를 열고
objViewer.View(token)을 호출합니다.
Search와 Annotation은 동일한 Viewer에 부착된 모듈이며 독립적인 툴바가 아닙니다. 메인 툴바는 호스트 애플리케이션에 속하고, Search와 Annotation 리본은 임베드된, 기능에 따라 접근이 제한된 리소스입니다.
ReferenceCss와 ReferenceScripts가 출력한 리소스로 현재 페이지가 정상 동작한 후에만 documentLinks.js 및 docViewer.UI.js와 같은 수동 복사 파일을 제거하십시오.
13. 플러그인 등록
정적 플러그인-라이선스 메서드는 현재 플러그인을 등록하지 않습니다. 각 릴리스된 패키지를 명시적으로 설치하고 등록하십시오:
builder.Services.AddDoconut(options =>
{
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
options.AddPlugin<Doconut.Plugins.Dicom.DicomPlugin>();
});AddDoconut()는 시작 시 등록된 플러그인 기능을 검증합니다. Converter와 DICOM은 릴리스된 .NET Standard 플러그인입니다. 일반 Search와 Annotation은 내장된 라이선스 기능이며, AddPlugin<TPlugin>() 패키지가 아닙니다.
14. 세션 및 문서 보안
현재 통합은 문서를 불투명 토큰 및 캐시된 세션에 바인딩합니다. 기본값인 UnsafeMode = false일 경우, UseDoconut()는 문서 접근 보안을 추가하며 호스트는 ASP.NET 세션을 구성해야 합니다:
builder.Services.AddDistributedMemoryCache(); // 세션 상태에 캐시가 필요합니다 (MVC/Razor Pages는 이미 하나를 추가합니다)
builder.Services.AddSession();
app.UseSession();DocOptions.IsSecured = true를 유지하십시오, 검토된 설계가 달리 요구하지 않는 한. 단일 노드에서 마이그레이션 단축키로 UnsafeMode = true를 절대 사용하지 마십시오. 토큰이 없거나, 형식이 잘못되었거나, 만료되었거나, 다른 브라우저 세션의 토큰을 사용한 요청을 테스트하십시오.
팜 환경에서는 페이지 요청이 처음 요청을 본 적이 없는 노드에 도달할 수 있어, 세션당 검사가 이를 거부합니다. 이것이 UnsafeMode = true가 올바른 유일한 경우이며, AddDoconutDistributedDocumentSecurity를 통해 서명된 접근 티켓과 함께 사용해야 하고, 단독으로 제공되어서는 안 됩니다. 자세히 보려면 분산 배포를 참조하십시오.
명명 주의사항
모든 프레임워크에서 클래스는 **Viewer**입니다. 오래된 코드 조각이나 타사 기사에서 DocumentViewer를 발견한다면, 해당 타입은 SDK에 존재하지 않았습니다.
15. 권장 작업 순서
- 호스트 프레임워크가 netstandard2.1을 사용할 수 있는지 확인하십시오. 사용할 수 없으면 중단합니다.
- 패키지를 26.8.0으로 올리고 빌드합니다. 컴파일 오류를 해결하십시오 — 대부분은 §1의
using라인입니다. - 시작 코드를
AddDoconut()로 이동하고 미들웨어 호출을 새로운 순서 (§3, §4)로 배치합니다. Viewer를 생성하던 위치에 주입하고,OpenDocument를 비동기로 만들며,InitCache()를 삭제합니다 (§5, §6).- 웹 팜을 사용하는 경우 §7을 수행하십시오 — 이름 변경이 아니라 재설계인 유일한 부분입니다.
- 문서를 변환하는 경우 §8을 수행하십시오.
- §11을 수행하십시오 — 클라이언트 측 변경 사항. 이들은 스스로 알리지 않는 부분입니다.
- 브라우저에서 실제 문서를 열고 로딩 스피너를 확인하십시오. 녹색 빌드는 여기서 아무것도 증명하지 못합니다: 라이선스, 플러그인 등록, 리소스 경로, 뷰어 콜백이 모두 런타임에만 실패합니다. 팜의 경우, 한 노드에서 게시된 문서가 다른 노드에서 제공되는지 확인하십시오.
마이그레이션 테스트
최소한 다음을 확인하십시오:
- 프로덕션 라이선스와 모든 등록된 플러그인을 사용한 애플리케이션 시작;
- 선택된 경로 아래의 Viewer CSS/스크립트와 모든 페이지-이미지 요청;
- 문서 열기, 탐색, 확대/축소, 썸네일, 인쇄 및 명시적 닫기;
- 텍스트가 포함된 문서에 대한 검색 및 이미지 전용 파일의 검색 불가능 상태;
- 주석 로드, 저장, 내보내기 및 기능 게이팅;
- 컨버터 대상 탐색, 출력, 다운로드 및 워터마크 상태;
- DICOM 페이지, 프레임 및 애니메이션; 기술 메타데이터는 이 패키지에서 사용할 수 없습니다;
- 비밀번호 보호 문서, 사용자 정의 글꼴, 비라틴 문자 및 구성된 타임아웃;
- 세션 간 토큰 거부 및 만료된 세션 동작;
- 팜의 경우: 한 노드에 게시하고 다른 노드에서 늦은 페이지를 요청하여 뷰어가 깨진 타일을 표시하는 대신
202응답을 재시도하는지 확인; - 모바일, 다크 모드 및 프로덕션 리버스 프록시 경로.
롤백 계획
이전 배포 아티팩트, 일치하는 패키지, 라이선스 파일 및 복사된 브라우저 리소스를 함께 보관하십시오. 안전한 롤백은 전체 애플리케이션 세대를 전환합니다; 이전 세대 서버와 현재 스크립트를 혼합하거나 현재 서버와 new Viewer(...) 호출 위치를 혼합하지 않습니다.
전환 전, 다음을 문서화하십시오:
- 롤백에 사용된 배포 슬롯 또는 아티팩트;
- 공유 스토리지에 미치는 영향(있는 경우) — 26.8.0에 의해 게시된 아티팩트는 이전 웹 팜 미들웨어에서 사용되지 않음;
- 활성 문서 세션이 어떻게 무효화될지;
- 롤백 결정을 위한 헬스 체크 및 스모크 문서;
- 이전 패키지 세트와 구성을 복원할 수 있는 사람.
레거시 문서
번역된 이전 매뉴얼은 레거시 .NET Standard 설정에서 여전히 사용할 수 있습니다. 이전 통합 게이트웨이는 동일한 식별 신호를 설명하고 이 마이그레이션 가이드로 다시 연결합니다.
netstandard2.0 설치가 여전히 존재하는 동안 즐겨찾기와 지원 티켓에 과거 URL을 유지하십시오. 이는 다른 세대를 문서화하며 현재 API로 리디렉션되지 않습니다.
이 페이지가 도움이 되었나요?