
튜토리얼: .NET 8에서 주입된 Doconut 뷰어로 문서 열기
소개
이전 Doconut 예제에서는 Viewer를 캐시, HTTP 컨텍스트 및 라이선스 경로 인수와 함께 직접 생성할 수 있습니다. 이는 현재 .NET 8 통합 모델이 아닙니다. AddDoconut()은 Viewer를 의존성 주입으로 등록하며, 애플리케이션 엔드포인트는 생성자를 호출하는 대신 서비스를 받습니다.

이 튜토리얼은 현재 요청 흐름을 따릅니다: 서비스와 미들웨어를 등록하고, 포함된 뷰어 리소스를 내보내며, OpenDocumentAsync로 문서를 열고, 불투명 세션 토큰을 반환한 뒤 해당 토큰을 브라우저 위젯에 전달합니다.
1. Doconut 설치 및 등록
.NET 8 패키지를 추가합니다:
dotnet add package Doconut.NET8
Doconut 및 ASP.NET 세션 서비스를 등록합니다:
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.MiddlewarePath = "/doconut";
options.ResourcesPath = "/doconut-res";
options.UnsafeMode = false;
});
builder.Services.AddSession();
필요한 순서대로 미들웨어를 연결합니다. 리소스 미들웨어는 최종 문서 미들웨어보다 먼저 실행되어야 합니다:
app.UseRouting();
app.UseSession();
app.UseDoconutResources();
app.Map("/doconut", branch => branch.UseDoconut());
MiddlewarePath는 구성을 조정하지만 자체적으로 ASP.NET 브랜치를 만들지는 않습니다. 매핑된 /doconut 경로는 위젯의 BasePath와 일치해야 합니다.
2. 뷰어 표면 및 리소스 추가
Doconut 브라우저 뷰어는 jQuery 플러그인입니다. Razor 페이지에서 Viewer를 주입하고, 의존성 순서대로 리소스 태그를 내보내도록 요청합니다:
@inject Doconut.Viewer Viewer
@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
IncludeViewerCss = true
}))
@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
IncludeJQuery = true,
IncludeViewerScripts = true
}))
<div id="divDocViewer">
<div id="div_ctlDoc"></div>
</div>
서버 등록과 일치하는 경로로 위젯을 초기화합니다:
const objViewer = $('#div_ctlDoc').docViewer({
showThumbs: true,
autoLoad: false,
pageZoom: 100,
FitType: 'width',
BasePath: '/doconut',
ResPath: '/doconut-res/images',
onError: function (message) {
console.error('Doconut viewer error:', message);
}
});
옵션의 대소문자는 중요합니다. 설치된 버전이 표시하는 이름을 사용하고, 하나의 스타일로 정규화하지 마세요.
3. Viewer 주입 및 문서 열기
Viewer는 트랜지언트 서비스로 등록됩니다. 엔드포인트 주입, 생성자 주입 또는 ASP.NET Core 애플리케이션에서 제공되는 동등한 방법으로 해결합니다.
app.MapPost("/api/open", async (
Viewer viewer,
CancellationToken ct) =>
{
string token = await viewer.OpenDocumentAsync(
"wwwroot/files/Sample.pdf",
ct: ct);
return Results.Ok(new { token });
});
업로드의 경우, 스트림과 파일 형식을 식별하는 FileInfo를 제공하십시오:
app.MapPost("/api/open-upload", async (
IFormFile file,
Viewer viewer,
CancellationToken ct) =>
{
await using var stream = file.OpenReadStream();
string token = await viewer.OpenDocumentAsync(
stream,
new FileInfo(file.FileName),
ct: ct);
return Results.Ok(new { token });
});
업로드 크기, 확장자 및 권한을 검증한 뒤 사용자 제공 콘텐츠를 열어야 합니다. 제출된 파일명을 서버 경로로 변환하지 마세요.
4. 토큰을 위젯에 전달
오픈 엔드포인트를 호출하고 반환된 토큰을 objViewer.View에 전달합니다:
fetch('/api/open', { method: 'POST' })
.then(response => {
if (!response.ok) throw new Error('The document could not be opened.');
return response.json();
})
.then(data => objViewer.View(data.token))
.catch(error => console.error(error));
토큰을 실시간 문서 세션을 위한 베어러 자격 증명으로 취급하십시오:
- 로그에 기록하거나 저장하지 마세요.
- 인증된 클라이언트에게만 반환하세요.
- 소스 파일 경로를 노출하지 마세요.
- 세션이 만료되면 문서를 다시 엽니다.
- 문서가 더 이상 필요하지 않을 때 세션을 종료합니다.
5. 서버 측 세션을 의도적으로 종료
사용자가 뷰어를 떠날 때 클라이언트 코드는 objViewer.Close()를 호출할 수 있습니다. 서버 워크플로우에서도 알려진 토큰을 명시적으로 취소할 수 있습니다:
app.MapPost("/api/close", (string token, Viewer viewer) =>
{
viewer.CloseDocument(token);
return Results.NoContent();
});
명시적 종료는 특히 큰 문서에 유용합니다. 세션 만료는 예비 수단이며, 예측 가능한 애플리케이션 수명 주기 관리를 대체하지 않습니다.
6. 핵심이 동작한 후에 선택적 모듈 추가
검색 및 주석은 동일하게 초기화된 뷰어에 부착됩니다. 기본 흐름이 성공한 뒤에 CSS, 스크립트, 마운트, 라이선스 검사 및 라이프사이클 콜백을 추가하십시오:
AddDoconut + session services
-> UseSession
-> UseDoconutResources
-> mapped UseDoconut branch
-> viewer resources and mount
-> initialize docViewer
-> OpenDocumentAsync
-> objViewer.View(token)
이 순서는 핵심 렌더링 오류를 선택적 모듈 구성과 분리합니다.
일반적인 마이그레이션 실수
| 이 이전 또는 잘못된 패턴 | 현재 .NET 8 방향 |
|---|---|
new Viewer(cache, accessor, licensePath) | AddDoconut() 이후에 Viewer를 주입합니다 |
| 요청 코드에서 정적 라이선스 로드 호출 | AddDoconut()에서 라이선스 입력을 구성합니다 |
| 동기 OpenDocument(...) 예제 | OpenDocumentAsync(...)를 사용합니다 |
| 외부 또는 임의의 뷰어 CDN | ReferenceCss와 ReferenceScripts로 포함된 리소스를 내보냅니다 |
| 일반적인 JavaScript init() API | $('#div_ctlDoc').docViewer(...)를 초기화합니다 |
| 뷰어 토큰 영구 저장 | 문서 ID를 영구 저장하고, 토큰은 일시적인 것으로 취급합니다 |
공식 Doconut 문서를 사용하고, 프로덕션 코드에 적용하기 전에 설치된 패키지 버전과 예제를 확인하십시오.