Migración

Doconut.NETFramework 26.8.0 (.NET Framework 4.7) a 26.9.0 (.NET Framework 4.7.2)

Esta página cubre la actualización de una aplicación ASP.NET existente desde Doconut.NETFramework 26.8.0 o anterior (.NET Framework 4.7) a 26.9.0 y posteriores (.NET Framework 4.7.2). El paquete de ejemplos Doconut incluye la guía completa de migración y los ejemplos clásicos portados a la nueva API — MVC 5, una granja web y Web Forms. Comparar su aplicación con el ejemplo del que partió es el camino más rápido.

Un paquete, dos versiones

Ambas bibliotecas se publican bajo el mismo ID de paquete, Doconut.NETFramework. La versión las diferencia:

VersiónObjetivoAPI
26.8.0 y anteriores.NET Framework 4.7la API anterior
26.9.0 y posteriores.NET Framework 4.7.2la nueva API

Actualizar el paquete es la actualización. No hay un paquete separado para instalar ni una capa de compatibilidad: 26.9.0 es una superficie de API diferente, así que espere errores de compilación después de la actualización — el resto de esta página. La línea .NET Framework 4.7 está descontinuada y 26.8.0 es su última versión. Puede permanecer en ella — nada aquí es una corrección de seguridad que se pierda — pero las nuevas versiones, complementos, el modo distribuido y los widgets listos para usar llegan solo en 26.9.0 y posteriores.

1. Cambiar el objetivo y actualizar el paquete

Cambie el objetivo del proyecto web a .NET Framework 4.7.2 primero: un proyecto que aún apunta a 4.7 no puede instalar 26.9.0, y NuGet rechaza la actualización. Luego actualice Doconut.NETFramework y añada los paquetes de complementos que utiliza (Doconut.NETFramework.Converter, Doconut.NETFramework.Dicom, …). Cada complemento necesita una licencia que lo autorice.

Si el proyecto usa packages.config, la actualización ejecuta el paso de desinstalación de la versión anterior, que elimina el controlador DocImage de Web.config, y 26.9.0 no lo vuelve a agregar. Regístrelo nuevamente como se muestra en el paso 3; hasta que lo haga, DocImage.axd responde 404 y ninguna página se renderiza.

2. Espacios de nombres: casi todo movido a la raíz

AntesAhora
using Doconut.Configs.View;using Doconut;
using Doconut.Models;using Doconut;
using Doconut.Configs;using Doconut;
using Doconut.Configs.Cloud;using Doconut.Clouds;
using Doconut.Configs.Conversion;sin cambios

Los nombres de tipo no cambiaron: WordConfig, PdfConfig, ExcelConfig, CssConfig, ScriptConfig, FileShareConfig y el resto siguen presentes. En la mayoría de los archivos, la edición completa consiste en eliminar líneas using.

3. Inicio: DoconutHost.Initialize y dos entradas de Web.config

El paquete clásico construía su visor por solicitud, con opciones como propiedades de esa instancia. El nuevo paquete tiene una raíz de composición, construida una vez en Application_Start, y el visor es un servicio que resuelve:

csharp
// Antes - Doconut.NETFramework 26.8.0 y anteriores, según solicitud
var viewer = new Viewer
{
    ID = "ctlDoc",
    IncludeJQuery = true,
    BasePath = "/",
    FitType = "width"
};
csharp
// Doconut.NETFramework 26.9.0\u002B - Visor resuelto desde DoconutHost, licencia configurada una vez en DoconutHost.Initialize()
var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
var token  = await viewer.OpenDocumentAsync(path, new PdfConfig { AllowSearch = true });

DoconutHost.Initialize va en Application_Start y DoconutHost.Shutdown en Application_End, y Web.config obtiene el controlador DocImage.axd y el módulo de recursos — ambos están en Instalación. Los ajustes de apariencia por página (FitType, FixedZoom, ShowHyperlinks, …) se movieron de la instancia del visor a las opciones del widget, o a un ViewerConfig pasado a Viewer.RenderViewer (ver ConfiguraciónDelVisor). new Viewer() todavía compila una vez que DoconutHost.Initialize se ha ejecutado, por lo que el código detrás migrado puede conservar esa línea mientras mueve los ajustes.

La seguridad funciona como antes. Abrir un documento otorga a la sesión actual de ASP.NET acceso a sus páginas, y DocImage.axd rechaza a todos los demás. La configuración de aplicación DoconutUnSafeMode que desactivaba esto ahora es options.UnsafeMode en DoconutHost.Initialize — déjela false. Ver Sesiones y Seguridad.

El fallo de inicio que derriba todo el sitio. Un complemento registrado cuya capacidad no está concedida por licencia lanza una excepción en Application_Start, y la aplicación entonces responde con un 500 vacío a cada solicitud — sin página de error, nada en el registro de IIS, solo una entrada en el registro de eventos de Windows (fuente ASP.NET). Las licencias se leen de wwwroot bajo la raíz del sitio y en ningún otro lugar, y el Doconut.Viewer.lic base debe estar presente o las licencias del complemento al lado no se leerán. Ver Configuración de Licencia.

4. Granja web: de una bandera al modo distribuido

El modelo clásico era viewer.IsWebfarm = true más ExportToPng(path). El nuevo modelo se registra una sola vez: cada nodo comparte un almacén y una clave de firma, y un ticket firmado vinculado al navegador reemplaza a "cualquier nodo que responda":

csharp
Doconut.DoconutHost.Initialize(
    options => options.UnsafeMode = false,
    services => services.AddDoconutDistributed(d =>
    {
        d.Store             = CloudLocation.FileShare;
        d.FileShareRootPath = @"\\fileserver\doconut-shared";   // WebfarmPath es un alias
        d.SigningKey        = farmKey;                           // >= 32 bytes, lo mismo en cada nodo
    }));

Luego abra los documentos normalmente, vinculando el navegador (DocOptions.BrowserId = DoconutFarmBinding.EnsureBrowserId(...)) y entregando viewer.AccessToken al widget con el token. Sesiones y Seguridad tiene los pasos; el ejemplo de granja web es un nodo completo. IsWebfarm y WebfarmPath todavía se compilan, pero ya no activan nada.

Dos cosas que parecen éxito pero no lo son: DistributedDocumentPublisher.PublishAsync escribe los archivos renderizados de un documento pero no abre sesión, por lo que un visor apuntado a un token publicado recibe la imagen de error de ~2 KB con estado 200; y un cliente de prueba sin la cookie doconut-client obtiene esa misma imagen, no un 401. Diferencie una página real de la imagen de error por su tamaño.

5. La conversión es un complemento, y mucho más pequeño

El enum SourceFormatConverter, las doce clases *ConfigConverter y sus enums de objetivo anidados se reemplazan por un único enum, ConversionTarget, y una única llamada:

csharp
using System.IO;
using System.Threading;
using Doconut;
using Doconut.Configs.Conversion;

// Suponga que DoconutHost ya está inicializado y que un CancellationToken llamado ct está disponible.
var provider = DoconutHost.Services;
var converter = (DocumentConverter)provider.GetService(typeof(DocumentConverter));
Stream source = /* su flujo de entrada */;
var result = await converter.ConvertAsync(source, ".dwg", ConversionTarget.Pdf, null, ct);

El formato de origen proviene de la extensión que pasa. No hay capa de compatibilidad: cada referencia a SourceFormatConverter es un error de compilación que resuelve eliminándola. Los objetos de opciones por formato no sobrevivieron — WordConfigConverter.HtmlOptions y CadConfigConverter.CadOptions.ShowColor no tienen equivalente a través de ConvertAsync. En Web Forms, nunca bloquee ConvertAsync — vea Complemento de Conversor.

6. Almacenamiento en la nube: accédalo como una carpeta compartida

Los tipos de configuración de la nube se trasladaron a Doconut.Clouds sin cambios. Sin embargo, los manejadores de solicitudes de la nube son componentes de ASP.NET Core, y una aplicación clásica no tiene una canalización para ejecutarlos. Desde un sitio System.Web, acceda al almacenamiento en la nube como una carpeta compartida — en Azure, un recurso Azure Files montado en cada nodo — accesible a través de FileShareConfig.

7. Cambios del lado del cliente que fallan silenciosamente

Cada elemento a continuación se compila, se ejecuta, no registra nada y hace lo incorrecto:

AntesAhora
ResPath: 'doconut-res'ResPath: 'doconut-res/images' — de lo contrario cada ícono devuelve 404 mientras el documento se renderiza
function ctlDoc_ViewerReady() { }docViewer({ onViewerReady: function () { } }) — las devoluciones de llamada del visor son opciones ahora
var viewer = $(el).docViewer({...}).View(token)Asigne docViewer(...) primero, luego llame a viewer.View(token) por separado
viewer.Refit() para ajustar a una páginaviewer.FitType('width') — Refit() solo recalcula el diseño
var n = viewer.Search(kw, exact)viewer.Search(kw, exact, function (n) { … }) — el recuento llega en la devolución de llamada
if (viewer.SaveAnnotations()) { … }docViewer({ onAnnSaved: …, onAnnSaveError: … })
function ctlDoc_Created() { } (annotations)Sin cambios — las funciones de eventos de anotación siguen siendo globales, encontradas por nombre

Tres más: el visor no dibuja su propia barra de herramientas (su página conecta Zoom, Next, GotoPage y el resto a sus propios botones); un visor creado dentro de un modal Bootstrap oculto mide 0×0 y no pinta nada hasta que le dé a su contenedor una altura explícita y lo reajuste en shown.bs.modal; y AllowSearch por defecto es false para PDF, por lo que un documento se renderiza perfectamente mientras cada búsqueda no devuelve nada.

8. Qué desaparece

DesaparecidoEn su lugar
DocumentSearch / TextSearch.csNada — la búsqueda se ejecuta sobre el texto que extraen los visores de formato
Viewer.WatermarkInfoSin equivalente
WordConfigConverter.HtmlOptionsNo hay objetos de opción a través de ConvertAsync
SourceFormatConverter, las clases *ConfigConverterConversionTarget y ConvertAsync
Doconut.Configs.EditorEliminado
viewer.IsWebfarm + ExportToPng(path)AddDoconutDistributed y apertura ordinaria

Orden sugerido de trabajo

  1. Redirigir, cambiar el paquete y lograr que Global.asax compile con DoconutHost.Initialize y los dos registros Web.config. El sitio debería iniciarse.
  2. Una página de visor: obtener un documento para renderizar, luego trabajar a través de la sección 7 hasta que la barra de herramientas, la búsqueda y las anotaciones funcionen. Verificar en un navegador real — nada en esa sección genera un error.
  3. Conversión (sección 5): mecánica, y la mayoría de los errores de compilación.
  4. Las páginas restantes, usando las muestras portadas como objetivo de diferencia.
  5. La granja web (sección 4), si tienes una. Prueba con dos nodos y un navegador, o un cliente que conserve cookies.

¿Fue útil esta página?