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:

csharp
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

  1. 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.
  2. 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 IMemoryCache sob um token GUID recém‑gerado com expiração deslizanteDocOptions.TimeOut minutos, padrão 60. Cada solicitação de página reinicia o relógio.
  3. Registro de segurança. Com UnsafeMode = false (o padrão), o token é vinculado à sessão ASP.NET do chamador: um marcador secure-{token} é gravado na sessão, de modo que somente a sessão do navegador que abriu o documento pode solicitar suas páginas.
  4. 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:

ConsultaPropósito
?token=…&page=NImagem da página renderizada (PNG)
?token=…&page=N&thumb=1Miniatura
?token=…&zoom=…Renderização da página com zoom
?token=…&search=termBusca em texto completo (restrita por licença)
?token=…&bookmarksEstrutura do documento/marcadores
?token=…&copy / &showlinks / &fileFormatCópia de texto, hyperlinks e informações de formato
?token=…&metaMetadados técnicos DICOM; retorna 501 para uma sessão DICOM no .NET 6
?token=…&action=rotate/flip/closeAções de página e fechamento explícito
?token=…&AnnSave=… / &AnnLoadSalvar/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 com Session 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

csharp
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.TimeOut precisa ser reaberto.
  • Viewer pode ser injetado e compartilhado livremente; as sessões carregam todo o estado.

Esta página foi útil?