Cómo funciona el Viewer
El ciclo de vida de la solicitud de documentos
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ás, 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 independientemente 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 temporizador. - Registro de seguridad. Con
UnsafeMode = false(el valor predeterminado), el token está vinculado a la sesión ASP.NET del solicitante: 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:
| Consulta | Propósito |
|---|---|
?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/marcadores del documento |
?token=…© / &showlinks / &fileFormat | Copia de texto, hipervínculos y información de formato |
?token=…&meta | Metadatos técnicos DICOM; devuelve 501 para una sesión DICOM en .NET 6 |
?token=…&action=rotate/flip/close | Acciones de página y cierre explícito |
?token=…&AnnSave=… / &AnnLoad | Guardar/cargar anotaciones |
Cada una de estas rutas 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 cortés 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?