Cómo funciona el visor

El ciclo de vida de la solicitud de documento

Doconut renderiza documentos como imágenes paginadas, servidas por un controlador HTTP que registra tu Web.config. Entender el ciclo de vida — apertura, token, solicitudes de página, cierre — explica casi todo el comportamiento que observarás, incluidos los mensajes de error.

Los componentes en movimiento

  • Viewer — el servicio público que resuelves desde DoconutHost.Services. Abre documentos y devuelve tokens de sesión.
  • La sesión del documento — un objeto del lado del servidor que mantiene el documento cargado, guardado en memoria bajo su token.
  • DocImage.axd — el Doconut.DocImageHandler declarado en Web.config. Responde a cada solicitud que hace el widget del navegador (páginas, miniaturas, búsqueda, anotaciones, …), siempre identificado por el token.
  • /doconut-res/* — el Doconut.DoconutResourceModule, que sirve los propios scripts, estilos e íconos del widget.

Viewer es sin estado — por diseño

Viewer no mantiene estado del documento por solicitud y no implementa IDisposable. Las sesiones viven independientemente de él y se limpian por expiración o mediante un CloseDocument(token) explícito. System.Web no tiene inyección de constructor, así que resuélvelo donde lo necesites — típicamente en una acción de controlador:

csharp
// POST /ViewerApi/Open?fileName=Sample.pdf
[HttpPost]
public async Task<ActionResult> Open(string fileName)
{
    var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
    var path   = Server.MapPath("~/files/" + Path.GetFileName(fileName));

    var token = await viewer.OpenDocumentAsync(path);
    return Content(token, "text/plain");
}

Qué ocurre dentro de OpenDocumentAsync

  1. Control de licencia. Una licencia rechazada (alterada, en lista negra, o una compilación fuera de la ventana de actualización de la licencia) lanza LicenseException inmediatamente, con la razón como mensaje. La apertura nunca se degrada silenciosamente por una licencia inválida; una licencia ausente solo agrega marcas de agua.
  2. Creación de sesión. La fábrica del visor elige el visor de formato según la extensión del archivo y carga el documento (ver Canal de Renderizado). La sesión se almacena en memoria bajo un nuevo token aleatorio con una expiración deslizante de DocOptions.TimeOut minutos (por defecto 60). Cada solicitud de página reinicia el temporizador.
  3. Concesión de acceso. Con UnsafeMode = false (el valor predeterminado), el token está vinculado a la sesión ASP.NET de la solicitud que lo abrió: se escribe una entrada secure-{token} en esa sesión. Por lo tanto, la apertura debe ejecutarse en una solicitud con estado de sesión — ver Sesiones y Seguridad.
  4. Se devuelve el token. Es el único identificador que el navegador necesita para todo lo que sigue.

Las sobrecargas asíncronas aceptan 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 selecciona el formato. Para código detrás de Web Forms que no usa páginas asíncronas, OpenDocument ofrece las mismas tres entradas de forma sincrónica (una ruta, un flujo con un nombre de archivo, o un arreglo de bytes con un nombre de archivo).

Cómo el widget obtiene páginas

El widget llama a DocImage.axd con el token en la cadena de consulta. Lo que hace el controlador 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 del documento y marcadores
?token=…&copy / &showlinks / &fileFormat / &metaCopia de texto, hipervínculos, información de formato, metadatos DICOM
?token=…&action=rotate/flip/closeAcciones de página y cierre explícito (POST)
?token=…&AnnSave=… / &AnnLoadGuardar y cargar anotaciones

Cada solicitud se verifica primero:

  • Sin token → 404, o un banner de versión cuando ShowDoconutInfo = true.
  • Token no concedido a esta sesión ASP.NET → una imagen de error que dice You Are Not Authorized To View This Page.
  • Token desconocido o expirado → una imagen de error que dice Document session not found. Please re-open document.

Las imágenes de error son PNG normales enviadas con el estado 200, de modo que el widget puede mostrarlas donde estaría la página. Una verificación de monitoreo que solo mira el código de estado las reportará como páginas servidas; una página real tiene decenas a cientos de kilobytes, mientras que una imagen de error ocupa alrededor de 2 KB.

Cerrando un documento

csharp
viewer.CloseDocument(token);

CloseDocument elimina la sesión (liberando el motor del documento y su memoria inmediatamente), elimina la entrada secure-{token} de la sesión ASP.NET de la solicitud actual y revoca el token. Es opcional — la expiración deslizante realiza la misma limpieza — pero para documentos grandes libera memoria en el momento en que el usuario termina. Desde el navegador, objViewer.Close(true) envía la solicitud de cierre equivalente a DocImage.axd.

Conclusiones

  • Un documento abierto = una sesión = un token, concedido a la sesión ASP.NET que lo abrió.
  • El token expira en una ventana deslizante; un visor que permanece inactivo más allá de DocOptions.TimeOut necesita volver a abrirse.
  • Viewer puede resolverse y compartirse libremente; las sesiones llevan todo el estado.

¿Fue útil esta página?