Cómo funciona el visor
El ciclo de vida de la solicitud de documento
Doconut renderiza documentos como imágenes paginadas servidas a través del middleware ASP.NET Core. Entender el ciclo de vida — abrir, token, solicitudes de página, cerrar — explica casi todo el comportamiento que observará, incluidos los mensajes de error.
Las tres partes móviles
Viewer— el servicio público que inyectas. Abre documentos y devuelve tokens de sesión.- La sesión del documento — un objeto del lado del servidor que mantiene el documento cargado, indexado por un token en
IMemoryCache. - El middleware Doconut — añadido por
UseDoconut(); responde a cada solicitud que hace el widget del navegador (pages,thumbnails,search,annotations, …), siempre autenticado por el token.
Viewer es sin estado — por diseño
Viewer está sellado, no mantiene estado de documento por solicitud y deliberadamente no implementa IDisposable. Las sesiones viven de forma independiente en el gestor de sesiones y se limpian por expiración de caché o mediante un CloseDocument(token) explícito.
Inyéctalo donde lo necesites:
app.MapPost("/api/open", async (string fileName, Viewer viewer) =>
{
var token = await viewer.OpenDocumentAsync($"files/{fileName}");
return Results.Content(token, "text/plain");
});Qué ocurre dentro de OpenDocumentAsync
- Control de licencia. Una licencia rechazada o caducada por versión (en lista negra, manipulada o una compilación fuera de la ventana de actualización de la licencia) lanza una
LicenseExceptioninmediatamente, con la razón del rechazo como mensaje — la apertura nunca se degrada silenciosamente por una licencia inválida (a diferencia de una ausente). Una licencia Temporal o de suscripción caducada por calendario es la excepción: no lanza — se degrada a una marca de agua. - Creación de sesión. La fábrica del visor elige el visor de formato correcto para la extensión del archivo y carga el documento (ver Rendering Pipeline). La sesión se almacena en
IMemoryCachebajo un nuevo token GUID con una expiración deslizante —DocOptions.TimeOutminutos, por defecto 60. Cada solicitud de página reinicia el contador. - Registro de seguridad. Con
UnsafeMode = false(el valor predeterminado), el token se vincula a la sesión ASP.NET del llamador: se escribe un marcadorsecure-{token}en la sesión, de modo que solo la sesión del navegador que abrió el documento pueda solicitar sus páginas. - Se devuelve el token. Es la única credencial para todo lo que sigue.
Las tres sobrecargas difieren solo en la entrada: una ruta de archivo, una ruta de archivo más una configuración por formato (PdfConfig, WordConfig, …), o un Stream más un FileInfo cuya extensión determina la detección del formato.
Cómo el widget obtiene páginas
El widget cliente llama al middleware Doconut con el token en la cadena de consulta. Lo que hace el middleware depende de la solicitud:
| Query | Purpose |
|---|---|
?token=…&page=N | Imagen de página renderizada (PNG) |
?token=…&page=N&thumb=1 | Miniatura |
?token=…&zoom=… | Renderizado de página con zoom |
?token=…&search=term | Búsqueda de texto completo (controlada por licencia) |
?token=…&bookmarks | Esquema del documento/marcadores |
?token=…© / &showlinks / &fileFormat / &meta | Copiar texto, hipervínculos, información de formato, metadatos técnicos DICOM |
?token=…&action=rotate/flip/close | Acciones de página y cierre explícito |
?token=…&AnnSave=… / &AnnLoad | Guardar/cargar anotaciones |
Cada una de estas rutas se valida primero:
- Sin token → el middleware devuelve 404 (o un banner de versión cuando
ShowDoconutInfo = true). - Token desconocido o expirado → una imagen de error con
Document session not found. Please re-open document. - Falta el middleware de sesión (con
UnsafeMode = false) → HTTP 500 conSession middleware not configured. Call UseSession() before UseDoconut(). - Token abierto por una sesión de navegador diferente → una imagen de error con
You Are Not Authorized To View This Page.
Cerrando un documento
viewer.CloseDocument(token);CloseDocument elimina la sesión de la caché (lo que dispone el motor de documento subyacente y libera su memoria inmediatamente), borra el marcador secure-{token} y revoca la concesión de acceso. Llamarlo es opcional — la expiración deslizante realiza la misma limpieza automáticamente — pero para documentos grandes es la forma educada de liberar memoria en el momento en que el usuario termina.
Conclusiones
- Un documento abierto = una sesión = un token. Los tokens son por sesión de navegador, no URLs globales.
- El token expira en una ventana deslizante; un visor que permanece inactivo más allá de
DocOptions.TimeOutnecesita volver a abrirse. Viewerpuede inyectarse y compartirse libremente; las sesiones llevan todo el estado.
¿Fue útil esta página?