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:

csharp
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

  1. 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 LicenseException inmediatamente, 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.
  2. 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 IMemoryCache bajo un nuevo token GUID con una expiración deslizanteDocOptions.TimeOut minutos, por defecto 60. Cada solicitud de página reinicia el temporizador.
  3. Registro de seguridad. Con UnsafeMode = false (el valor predeterminado), el token está vinculado a la sesión ASP.NET del solicitante: se escribe un marcador secure-{token} en la sesión, de modo que solo la sesión del navegador que abrió el documento pueda solicitar sus páginas.
  4. 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:

ConsultaPropósito
?token=…&page=NImagen de página renderizada (PNG)
?token=…&page=N&thumb=1Miniatura
?token=…&zoom=…Renderizado de página con zoom
?token=…&search=termBúsqueda de texto completo (controlada por licencia)
?token=…&bookmarksEsquema/marcadores del documento
?token=…&copy / &showlinks / &fileFormatCopia de texto, hipervínculos y información de formato
?token=…&metaMetadatos técnicos DICOM; devuelve 501 para una sesión DICOM en .NET 6
?token=…&action=rotate/flip/closeAcciones de página y cierre explícito
?token=…&AnnSave=… / &AnnLoadGuardar/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 con Session 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

csharp
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.TimeOut necesita volver a abrirse.
  • Viewer puede inyectarse y compartirse libremente; las sesiones llevan todo el estado.

¿Fue útil esta página?