Como o Visualizador Funciona
O ciclo de vida da solicitação de documentos
Doconut renderiza documentos como imagens paginadas servidas através de middleware ASP.NET Core. Compreender o ciclo de vida — abrir, token, solicitações de página, fechar — explica quase todo comportamento que você observará, incluindo as mensagens de erro.
As três partes móveis
Viewer— o serviço público que você injeta. Ele abre documentos e devolve tokens de sessão.- A sessão de documento — um objeto do lado do servidor que mantém o documento carregado, indexado por um token em
IMemoryCache. - O middleware Doconut — adicionado por
UseDoconut(); responde a todas as solicitações que o widget do navegador faz (pages,thumbnails,search,annotations, …), sempre autenticado pelo token.
Viewer é sem estado — por design
Viewer é selado, não mantém estado de documento por solicitação e deliberadamente não implementa IDisposable. As sessões vivem independentemente no gerenciador de sessões e são limpas por expiração do cache ou por um CloseDocument(token) explícito.
Injete‑o onde precisar:
app.MapPost("/api/open", async (string fileName, Viewer viewer) =>
{
var token = await viewer.OpenDocumentAsync($"files/{fileName}");
return Results.Content(token, "text/plain");
});O que acontece dentro de OpenDocumentAsync
- Portão de licença. Uma licença rejeitada ou expirado por versão (lista negra, adulterada ou uma compilação fora da janela de atualização da licença) lança imediatamente uma
LicenseException, com o motivo da rejeição como mensagem — a abertura nunca regride silenciosamente para uma licença inválida (em contraste com ausente). Uma licença Temporária ou de assinatura expirado por calendário é a exceção: não lança — regride para uma marca d'água. - Criação de sessão. A fábrica do visualizador escolhe o visualizador de formato correto para a extensão do arquivo e carrega o documento (veja Pipeline de Renderização). A sessão é armazenada em
IMemoryCachesob um token GUID recém‑gerado com expiração deslizante —DocOptions.TimeOutminutos, padrão 60. Cada solicitação de página reinicia o relógio. - Registro de segurança. Com
UnsafeMode = false(o padrão), o token é vinculado à sessão ASP.NET do chamador: um marcadorsecure-{token}é gravado na sessão, de modo que somente a sessão do navegador que abriu o documento pode solicitar suas páginas. - O token é retornado. Ele é a única credencial para tudo que se segue.
Os três overloads diferem apenas na entrada: um caminho de arquivo, um caminho de arquivo mais uma configuração por formato (PdfConfig, WordConfig, …), ou um Stream mais um FileInfo cuja extensão determina a detecção de formato.
Como o widget obtém páginas
O widget cliente chama o middleware Doconut com o token na string de consulta. O que o middleware faz depende da solicitação:
| Consulta | Propósito |
|---|---|
?token=…&page=N | Imagem da página renderizada (PNG) |
?token=…&page=N&thumb=1 | Miniatura |
?token=…&zoom=… | Renderização da página com zoom |
?token=…&search=term | Busca em texto completo (restrita por licença) |
?token=…&bookmarks | Estrutura do documento/marcadores |
?token=…© / &showlinks / &fileFormat | Cópia de texto, hyperlinks e informações de formato |
?token=…&meta | Metadados técnicos DICOM; retorna 501 para uma sessão DICOM no .NET 6 |
?token=…&action=rotate/flip/close | Ações de página e fechamento explícito |
?token=…&AnnSave=… / &AnnLoad | Salvar/carregar anotações |
Cada um desses caminhos valida primeiro:
- Sem token → o middleware retorna 404 (ou um banner de versão quando
ShowDoconutInfo = true). - Token desconhecido ou expirado → uma imagem de erro com
Document session not found. Please re-open document. - Middleware de sessão ausente (com
UnsafeMode = false) → HTTP 500 comSession middleware not configured. Call UseSession() before UseDoconut(). - Token aberto por uma sessão de navegador diferente → uma imagem de erro com
You Are Not Authorized To View This Page.
Fechando um documento
viewer.CloseDocument(token);CloseDocument remove a sessão do cache (que descarta o mecanismo de documento subjacente e libera sua memória imediatamente), exclui o marcador secure-{token} e revoga a concessão de acesso. Chamá‑lo é opcional — a expiração deslizante faz a mesma limpeza automaticamente — mas para documentos grandes é a forma educada de liberar memória assim que o usuário termina.
Conclusões
- Um documento aberto = uma sessão = um token. Tokens são por sessão de navegador, não URLs globais.
- O token expira em uma janela deslizante; um visualizador deixado ocioso além de
DocOptions.TimeOutprecisa ser reaberto. Viewerpode ser injetado e compartilhado livremente; as sessões carregam todo o estado.
Esta página foi útil?