Migrar a .NET Standard 2.1
Mover una aplicación Doconut.NETStandard existente de 26.7.0 a 26.8.0
Doconut tiene dos integraciones distintas de .NET Standard. Utilizan el mismo nombre de paquete Doconut.NETStandard, por lo que debe identificar la generación a partir de la versión y de las API en la aplicación antes de cambiar paquetes, inicio, licencias o recursos del navegador.
La versión es la bifurcación del camino
Ambas generaciones publican bajo el mismo ID de paquete. Sólo la versión las diferencia:
| Versión | Objetivo | API |
|---|---|---|
| 26.7.0 y versiones anteriores | netstandard2.0 | la API anterior |
| 26.8.0 y versiones posteriores | netstandard2.1 | la API actual |
Incrementar el número de versión es la actualización. No hay un paquete separado para instalar y no existe un shim de compatibilidad — 26.8.0 es una superficie de API diferente. Espere errores de compilación después del incremento; el resto de esta guía es la lista de ellos.
¿Qué integración está usando?
| Si el proyecto contiene… | Generación |
|---|---|
new Viewer(_cache, _accessor, ...) | Anterior |
viewer.OpenDocument(...) (synchronous) | Anterior |
viewer.InitCache() | Anterior |
UseDoconut(new DoconutOptions { ... }) | Anterior |
UseDoconutWebFarm(...) / WebFarmOptions | Anterior |
Viewer.DoconutLicense(...) or Viewer.SetLicensePlugin(...) | Anterior |
viewer.Converter.GetConverter() | Anterior |
using Doconut.Configs; / using Doconut.Models; | Anterior |
Manually copied docViewer.js, documentLinks.js, or docViewer.UI.js | Anterior |
builder.Services.AddDoconut(...) | Actual |
app.UseDoconutResources() plus app.UseDoconut() with no arguments | Actual |
Viewer supplied by dependency injection | Actual |
await viewer.OpenDocumentAsync(...) | Actual |
Si ambas columnas aparecen en la misma aplicación, trate la migración como incompleta. No envíe un token de documento a través de recursos o middleware de la otra generación.
Verifique primero el framework host
Esto es una barrera estricta, no una preferencia. El paquete actual apunta a netstandard2.1:
| Host | ¿Puede consumir 26.8.0? |
|---|---|
| .NET Core 3.0 o posterior (incluyendo .NET 5/6/7/8) | Sí |
| .NET Framework, cualquier versión | No |
.NET Framework no puede referenciar una biblioteca netstandard2.1. Si la aplicación se ejecuta en .NET Framework, deténgase aquí y use el paquete Doconut.NETFramework en su lugar; a partir de la 26.9.0 requiere .NET Framework 4.7.2. Ambas aplicaciones de referencia para esta versión apuntan a net8.0.
Antes de migrar
- Cree una rama y una copia de seguridad desplegable de la aplicación existente.
- Registre las versiones exactas de los paquetes core y de plugins.
- Inventariar cada llamada
new Viewer(...), cada llamadaInitCache(), cada carga de licencia, cada mapeoUseDoconutWebFarm, controlador de conversión, script Doconut copiado, acción de barra de herramientas personalizada, devolución de llamada del visor y punto final de apertura de documento. - Conserve los archivos
.licactuales y los secretos de despliegue fuera del control de versiones. - Capture un conjunto representativo de documentos PDF, Office, imagen, CAD, correo electrónico, DICOM, buscables, protegidos con contraseña y anotados.
- Registre el tiempo de expiración de sesión existente, el comportamiento de seguridad, las fuentes y la configuración de la plataforma.
Migre un entorno antes de cambiar la producción. La integración actual cambia la vida útil del servicio, el enrutamiento de solicitudes, la propiedad de la sesión, la entrega de recursos al cliente y — si ejecuta una granja — cómo las páginas llegan al navegador.
1. Espacios de nombres: casi todo movido a la raíz
Los tipos de configuración estaban repartidos en cuatro espacios de nombres. Ahora todos están en Doconut.
| Antes | Ahora |
|---|---|
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 |
using Doconut.Middleware; | sin cambios |
Los nombres de tipo no cambiaron: WordConfig, PdfConfig, ExcelConfig, CssConfig, ScriptConfig, CloudUploadConfig, AzureConfig, CDNConfig, FileShareConfig y el resto siguen presentes. En la mayoría de los archivos, la edición completa consiste en eliminar dos líneas using.
Doconut.Configs.Editor (BaseConfigEditor, PdfConfigEditor) se eliminó y no tiene reemplazo en este paquete. Si su aplicación hacía referencia a esos tipos, planifique esa parte por separado y no la considere parte de esta migración.
2. Compatibilidad de paquetes y licencias
Reemplace o actualice deliberadamente el paquete central; no confíe en que el ID de paquete idéntico seleccione la nueva API. El comando predeterminado instala la última versión estable:
dotnet add package Doconut.NETStandardPara una migración reproducible a la versión auditada por esta guía, pase la versión como una opción separada:
dotnet add package Doconut.NETStandard --version 26.8.0Mantenga cada complemento de Doconut en la misma versión que el paquete central — Doconut.NETStandard.Converter y Doconut.NETStandard.Dicom. La integración actual carga licencias una sola vez durante AddDoconut(), usando esta precedencia:
LicenseStream > LicenseContent > LicensePath > automatic discoveryLa detección automática busca archivos Doconut.Viewer.lic y sus complementos Doconut.Viewer.<Capability>.lic. Las llamadas estáticas anteriores Viewer.DoconutLicense(...) y Viewer.SetLicensePlugin(...) ya no son un mecanismo de inicio actual, y tampoco lo es la List<string> de rutas de licencia que aceptaba el constructor antiguo de Viewer. Mueva la licencia a DoconutOptions, mantenga los archivos complementarios juntos al usar la detección automática, reinicie después de cambiar una licencia y verifique las capacidades mediante IDoconutLicenseService.
No asuma que la presencia de una licencia de complemento antigua pruebe el derecho a una compilación de complemento actual. Pruebe Viewer, Search, Annotation, Converter y DICOM por separado con los artefactos de la versión aprobada.
3. Inicio e inyección de dependencias
Anteriormente el visor se construía por solicitud y las opciones se pasaban al middleware:
// Integración anterior — solo como contraste; no compile esto con el SDK actual.
var viewer = new Viewer(_cache, _accessor);
// …
appBranch.UseDoconut(new DoconutOptions { UnSafeMode = false, ShowDoconutInfo = false });La integración actual registra Doconut una sola vez y recibe Viewer mediante inyección de dependencias:
builder.Services.AddDoconut(options =>
{
options.UnsafeMode = false; // nota el cambio de ortografía: UnSafeMode → UnsafeMode
options.ShowDoconutInfo = false;
options.LicensePath = "Doconut.Viewer.lic";
});
builder.Services.AddDistributedMemoryCache(); // session state needs a cache (MVC/Razor Pages already add one)
builder.Services.AddSession();
app.UseSession();
app.UseDoconutResources();
app.UseDoconut();Viewer es un servicio transitorio. El gestor de sesión del documento y su caché poseen el estado del documento de mayor duración, no la instancia inyectada específica de Viewer.
Tres cosas a trasladar:
new Viewer(cache, accessor)ha desaparecido. InyecteDoconut.Vieweren su controlador, o use@inject Doconut.Viewer Vieweren una vista Razor.UseDoconutResources()reemplaza la conexión manualapp.UseMiddleware<EmbeddedResourceMiddleware>(), y debe ejecutarse antes de la rama del documento.UnSafeMode→UnsafeMode. Un cambio de un carácter que el compilador detectará.
Cuando UnsafeMode es false el SDK valida el token de sesión contra la solicitud originaria, por lo que AddSession() / UseSession() deben seguir en la canalización, UseSession() antes de la rama.
Métodos que ya no existen
| Antes | Ahora |
|---|---|
viewer.OpenDocument(path, config, options) | await viewer.OpenDocumentAsync(path, config, options) |
viewer.InitCache() | eliminado — no hay nada que calentar manualmente; elimine la llamada y cualquier bandera de "¿ya inicialicé?" alrededor |
viewer.ExportToPng(sharedPath) | ver §7 |
viewer.ExportToCloud(cloudConfig) | ver §7 |
using var v = new Viewer(...); v.CloseDocument(t) | viewer.CloseDocument(token) en la instancia inyectada |
4. Middleware y enrutamiento de recursos
UseDoconut() ahora no recibe argumentos. La forma de la rama MapWhen en sí no necesita cambiar — solo el middleware dentro de ella:
app.UseDoconutResources(); // BEFORE the branch
app.MapWhen(
ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
branch => branch.UseDoconut());En la canalización actual:
- llame a
UseSession()antes de Doconut mientras la seguridad de sesión está habilitada; - llame a
UseDoconutResources()antes deUseDoconut(); - mantenga
ResourcesPath, las URLs de recursos generadas, y elResPathdel cliente alineados; - mantenga la rama que mapea y el
BasePathdel cliente alineados.
MiddlewarePath es una configuración validada; no crea una rama de ASP.NET Core por sí mismo.
5. Construcción y ciclo de vida del Viewer
Elimine las cachés de la aplicación que poseen objetos Viewer. No queda nada en un Viewer que valga la pena conservar: no lleva estado de documento, y la caché de sesión posee todo lo que sobrevive a una solicitud. Inyéctelo en un endpoint, página Razor, controlador o servicio de aplicación con alcance:
app.MapPost("/api/open", async (Viewer viewer) =>
{
var token = await viewer.OpenDocumentAsync("wwwroot/files/Sample.pdf");
return Results.Ok(new { token });
});El token devuelto identifica una sesión de documento del lado del servidor. Trátelo como una credencial portadora: no lo registre, no lo persista ni lo incluya en análisis.
6. Apertura y cierre de documentos
Reemplace OpenDocument(...) sincrónico con OpenDocumentAsync(...):
// Integración actual: Viewer proviene de DI y la apertura del documento es asíncrona.
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { AllowSearch = true });Las sobrecargas actuales aceptan una ruta de archivo o un flujo, una configuración de formato opcional, DocOptions opcional y un token de cancelación. Cierre la sesión del servidor explícitamente cuando el navegador ya no la necesite:
viewer.CloseDocument(token);Elimine cualquier llamada a InitCache() y la bandera que la protege — no hay nada que calentar manualmente. No reutilice un token generado por la biblioteca anterior después del cambio: abra cada documento nuevamente mediante la API actual.
7. Web farm → distribuido: el mayor cambio
UseDoconutWebFarm y WebFarmOptions ya no existen. Si su aplicación los llama, esta sección es su actualización; si no lo hace, pase a la §8.
Anteriormente un solo middleware hacía todo: servía imágenes pre‑renderizadas desde una carpeta compartida y consultaba mientras otro nodo todavía las escribía.
// Integración anterior — una llamada, coordinación implícita a través del sistema de archivos.
appBranch.UseDoconutWebFarm(new WebFarmOptions
{
Path = Path.Combine(env.WebRootPath, "webfarm"),
PageWaitTimeSeconds = 180,
StartWaitFromPage = 5,
});La misma tarea ahora se divide en dos mitades explícitas. Lado de escritura — el nodo que abre el documento publica todo el conjunto de artefactos (páginas, información del documento, índice de búsqueda, metadatos) en el recurso compartido:
var result = await _publisher.PublishAsync( // DistributedDocumentPublisher, inyectado desde DI
pathToFile,
new FileShareConfig
{
Location = CloudLocation.FileShare,
RootPath = @"\\fileserver\doconut", // la misma carpeta que usa hoy
UsePerTokenSubfolders = true,
},
config,
documentOptions,
new DistributedDocumentPublishOptions
{
CleanUpStagingDirectory = true,
FirstPagePriority = true,
});
return Content(result.Token);Lado de lectura — cualquier nodo sirve desde el recurso compartido:
app.MapWhen(
ctx => ctx.Request.Path.Value?.EndsWith("DocImage.axd", StringComparison.OrdinalIgnoreCase) == true,
branch => branch.UseDoconutCloud<FileShareCloudHandler>(options =>
{
options.Location = CloudLocation.FileShare;
options.CloudUploadConfig = /* el MISMO FileShareConfig que arriba */;
}, "/"));| Antes | Ahora |
|---|---|
WebFarmOptions.Path | FileShareConfig.RootPath |
PageWaitTimeSeconds / StartWaitFromPage | eliminado — reemplazado por FirstPagePriority en el lado de escritura más FileShareConfig.ReadReadyPollMs en el lado de lectura |
viewer.OpenDocument(...) then viewer.ExportToPng(share) | una llamada a PublishAsync(...) |
DocOptions.IsWebfarm / WebfarmPath | todavía allí, escrito IsWebFarm / WebFarmPath — pero no se necesita en la ruta de publicación |
Su topología no cambia. Apunte RootPath al mismo recurso UNC y cada nodo seguirá funcionando como lo hace hoy. Lo que cambia es que la publicación es una operación que usted llama, en lugar de un efecto secundario del renderizado.
Ambas mitades deben coincidir. Si
RootPathoUsePerTokenSubfoldersdifieren entre el publicador y el manejador, el otro nodo responderá 404. Construya la configuración en un ayudante y llámela desde ambos lados.
PageWaitTimeSeconds = 180 significaba "bloquear hasta tres minutos esperando que la página aparezca". El reemplazo es explícito: con FirstPagePriority = true, la página 1 es servible inmediatamente y las páginas posteriores responden HTTP 202 Accepted hasta que se escriban. El visor incluido reintenta automáticamente cuando retryOn409 está activado. Un cliente que no reintente mostrará mosaicos rotos para las páginas que aún se están renderizando.
El arreglo completo, incluyendo la publicación en segundo plano y los tickets de acceso, está en Despliegues Distribuidos.
8. La conversión es un plugin, y mucho más pequeño
Registre el plugin, luego inyecte la fachada DocumentConverter:
builder.Services.AddDoconut(o => o.AddPlugin<ConverterPlugin>());// Integración anterior
var converter = viewer.Converter.GetConverter();
var config = new WordConfigConverter { TargetFormat = WordConfigConverter.EnTargetFormat.PDF };
var result = converter.Convert(stream, SourceFormatConverter.DOCX, config);
// Integración actual
var result = await _converter.ConvertAsync(stream, ".docx", ConversionTarget.Pdf, null, ct);Lo que eso reemplaza:
SourceFormatConverter— eliminado. Pase la extensión del archivo como una cadena, incluido el punto.- Los tipos
*ConfigConverterpor familia (WordConfigConverter,ExcelConfigConverter, …), cada uno con un enum anidadoEnTargetFormat— eliminado. Ahora hay un enumConversionTargetpara cada familia. viewer.Converter.GetConverter()— eliminado. InyecteDoconut.DocumentConverter.
ConvertAsync devuelve un flujo buscable, por lo que return File(result, mime, name) funciona directamente — la copia MemoryStream que necesitaba el código anterior es innecesaria. En el ejemplo incluido esto eliminó un interruptor de extensiones de 68 casos y diez controladores casi idénticos.
Vea el Plugin de Conversor para obtener la información completa.
9. Proveedores de nube
UseDoconutCloud se volvió genérico. El proveedor es el argumento de tipo en lugar de un valor Location conmutado dentro del middleware:
// Integración anterior
appBranch.UseDoconutCloud(new CloudOptions { Location = CloudLocation.CDN, ... });
// Integración actual
branch.UseDoconutCloud<CDNCloudHandler>(options =>
{
options.Location = CloudLocation.CDN;
options.CloudUploadConfig = new CDNConfig { DoconutCdnUrl = "..." };
}, "/");Las clases de configuración no cambian, salvo por el espacio de nombres (Doconut.Configs.Cloud → Doconut.Clouds): AzureConfig, AmazonConfig, GoogleCloudConfig, DropBoxConfig, RedisConfig, CDNConfig, FTPConfig, además del nuevo FileShareConfig. Los manejadores se nombran <Provider>CloudHandler.
El manejador CDN es solo lectura — sirve lo que ya está en el CDN; no sube archivos.
10. Objetos de configuración que cambiaron de nombre
| Antes | Ahora |
|---|---|
DoconutOptions.UnSafeMode | UnsafeMode |
DocOptions.IsWebfarm | IsWebFarm |
DocOptions.WebfarmPath | WebFarmPath |
DocOptions.ImageResolution | todavía presente pero obsoleta — establezca la resolución en la configuración del formato en su lugar |
DocOptions también gana IsSecured.
La API actual también separa las preocupaciones de forma más estricta que la anterior, así que verifique que cada configuración esté en el objeto que ahora la posee:
| Preocupación | Tipo actual |
|---|---|
| Rutas de middleware, licencias, registro de plugins | DoconutOptions |
| Contraseña, tiempo de espera, seguridad, marca de agua | DocOptions |
| Renderizado de formato y DPI | PdfConfig, WordConfig, ExcelConfig, y otros tipos BaseConfig |
| Valores predeterminados del widget del navegador | ViewerConfig o las opciones equivalentes de JavaScript |
| CSS y scripts generados | CssConfig y ScriptConfig |
| Almacenamiento compartido y proveedores de nube | FileShareConfig y las demás configuraciones de Doconut.Clouds |
No traslade DocOptions.ImageResolution como control de renderizado. Está obsoleta; establezca BaseConfig.ImageResolution en la configuración específica del formato. Revise todos los valores predeterminados en lugar de asumir que una configuración anterior tiene el mismo comportamiento.
11. El visor del lado del cliente — dos cambios que fallan SILENCIOSAMENTE
Ambos dejan el servidor funcionando perfectamente. Su documento se renderiza, la página se ve bien y nada aparece en la consola del navegador. Lea esta sección aunque su C# compile a la primera.
Las devoluciones de llamada del visor son opciones ahora, no funciones globales
El visor anterior llamaba a sus manejadores por nombre, derivando el nombre de la función global del id del contenedor. Declarar function ctlDoc_OnViewerReady() en una página con <div id="div_ctlDoc"> era suficiente. El visor actual toma devoluciones de llamada explícitas en el objeto de opciones y ya no busca esas funciones globales:
objctlDoc = $("#div_ctlDoc").docViewer({
// ... tus opciones existentes ...
onViewerBusy: ctlDoc_OnViewerBusy, // se encontraba por nombre
onViewerReady: ctlDoc_OnViewerReady, // se encontraba por nombre
onCopy: ctlDoc_Copy, // era ctlDoc_Copy(text)
onAutoLoadStatus: ctlDoc_AutoLoadStatus // era ctlDoc_AutoLoadStatus(page)
});Por qué esto es problemático: la llamada anterior estaba envuelta en un catch vacío, que atrapaba todo. Ahora sus funciones simplemente nunca se ejecutan y nada informa un error. El síntoma habitual es un indicador de carga que nunca se detiene — porque la función que lo ocultaba era ctlDoc_OnViewerReady. El documento detrás de ella está bien.
La lista completa de opciones es onPageLoading, onPageLoaded, onThumbnailClicked, onPageClicked, onDoubleClick, onViewerBusy, onViewerReady, onViewerError, onCopy, onAnnSaved, onAnnSaveError, onAnnLoaded, onAnnClosed, onAutoLoadStatus, onThumbsShown y onError. No hay una devolución de llamada para clic en enlaces: el manejo de hipervínculos está integrado, impulsado por showHyperlinks.
ResPath debe apuntar al prefijo del recurso
ResPath: '', // ANTES — los recursos provenían de la raíz de la aplicación
ResPath: 'doconut-res/images', // AHORA — el prefijo que monta UseDoconutResources()Si cambiaste el prefijo mediante DoconutOptions.ResourcesPath, usa ese valor en su lugar.
12. Barra de herramientas del visor, búsqueda y anotación
No migres los scripts antiguos uno por uno. Las aplicaciones de referencia actuales componen un paquete de página completo:
- emitir el CSS del Visor y el CSS con licencia de Búsqueda/Anotación con
ReferenceCss; - renderizar la barra de herramientas del Visor perteneciente a la aplicación;
- renderizar
searchBarMount,annBarMounty el montaje del Visor requerido; - emitir los scripts del Visor y de los módulos con licencia con
ReferenceScripts; - cargar el script auxiliar de la barra de herramientas propio de la aplicación;
- inicializar un
objViewer; - inicializar las cintas de Búsqueda y Anotación con licencia;
- llamar a
attach(objViewer)en cada cinta; - abrir el documento y llamar a
objViewer.View(token).
Búsqueda y Anotación son módulos adjuntos al mismo Visor, no barras de herramientas independientes. La barra de herramientas principal pertenece a la aplicación anfitriona; las cintas de Búsqueda y Anotación están incrustadas, recursos con control de capacidades.
Elimina los archivos copiados manualmente como documentLinks.js y docViewer.UI.js solo después de que la página actual funcione con los recursos emitidos por ReferenceCss y ReferenceScripts.
13. Registro de complementos
Los métodos estáticos de licencia de complementos no registran los complementos actuales. Instala y registra cada paquete lanzado explícitamente:
builder.Services.AddDoconut(options =>
{
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
options.AddPlugin<Doconut.Plugins.Dicom.DicomPlugin>();
});builder.Services.AddDistributedMemoryCache(); // el estado de sesión necesita una caché (MVC/Razor Pages ya añaden una)
builder.Services.AddSession();
app.UseSession();AddDoconut() valida las capacidades de los complementos registrados al iniciar. Converter y DICOM son los complementos .NET Standard lanzados. Búsqueda y Anotación normales son funciones con licencia integradas, no paquetes AddPlugin<TPlugin>().
14. Seguridad de sesión y documento
La integración actual vincula documentos a tokens opacos y sesiones en caché. Con el valor predeterminado UnsafeMode = false, UseDoconut() agrega seguridad de acceso a documentos y el anfitrión debe configurar la sesión de ASP.NET:
Mantén DocOptions.IsSecured = true a menos que un diseño revisado requiera lo contrario. Nunca uses UnsafeMode = true como atajo de migración en un solo nodo. Prueba solicitudes sin token, con un token malformado, un token expirado y un token de una sesión de navegador diferente.
En una granja, la solicitud de página puede llegar a un nodo que nunca vio la solicitud inicial, por lo que la verificación por sesión la rechazaría. Ese es el único caso en que UnsafeMode = true es correcto — y debe combinarse con tickets de acceso firmados mediante AddDoconutDistributedDocumentSecurity, no distribuido por sí solo. Ver Despliegues Distribuidos.
Nota de nomenclatura
En todos los frameworks la clase es Viewer. Si encuentras DocumentViewer en fragmentos antiguos o artículos de terceros, ese tipo nunca existió en el SDK.
15. Orden de trabajo sugerido
- Confirma que el framework anfitrión pueda consumir netstandard2.1. Si no puede, detente.
- Actualiza el paquete a 26.8.0 y compila. Resuelve los errores de compilación — la mayoría son las líneas
usingen §1. - Mueve el inicio a
AddDoconut()y las llamadas al middleware a su nuevo orden (§3, §4). - Inyecta
Viewerdonde lo estabas construyendo, haz queOpenDocumentsea async, y eliminaInitCache()(§5, §6). - Si usas la granja web, realiza §7 — la única parte que es un rediseño en lugar de un cambio de nombre.
- Si conviertes documentos, realiza §8.
- Haz §11 — los cambios del lado del cliente. Son los que no se anunciarán por sí mismos.
- Abre un documento real en un navegador y observa el indicador de carga. Una compilación verde no prueba nada aquí: la licencia, el registro de complementos, la ruta del recurso y las devoluciones de llamada del visor fallan solo en tiempo de ejecución. Para una granja, verifica que un documento publicado por un nodo sea servido por otro.
Probando la migración
Como mínimo, verificar:
- inicio de la aplicación con la licencia de producción y todos los complementos registrados;
- CSS/scripts del Viewer y todas las solicitudes de imágenes de página bajo las rutas elegidas;
- apertura del documento, navegación, zoom, miniaturas, impresión y cierre explícito;
- búsqueda en un documento con texto y el estado no buscable de un archivo solo de imagen;
- carga, guardado, exportación de anotaciones y control de capacidades;
- descubrimiento del objetivo del convertidor, salida, descarga y estado de la marca de agua;
- páginas, fotogramas y animación DICOM; los metadatos técnicos no están disponibles en este paquete;
- documentos protegidos con contraseña, fuentes personalizadas, texto no latino y tiempos de espera configurados;
- rechazo de tokens entre sesiones y comportamiento de sesión expirada;
- para una granja: publicar en un nodo, solicitar una página tardía desde otro, y confirmar que el visor reintenta respuestas
202en lugar de mostrar mosaicos rotos; - móvil, modo oscuro y la ruta del proxy inverso de producción.
Plan de reversión
Mantenga el artefacto de despliegue anterior, los paquetes coincidentes, los archivos de licencia y los recursos del navegador copiados juntos. Una reversión segura cambia toda la generación de la aplicación; no mezcla un servidor de generación anterior con scripts actuales, ni un servidor actual con sitios de llamada new Viewer(...).
Antes del cambio, documente:
- la ranura o artefacto de despliegue usado para la reversión;
- el impacto del almacenamiento compartido, si lo hay — los artefactos publicados por 26.8.0 no son consumidos por el middleware de la granja web anterior;
- cómo se invalidarán las sesiones de documentos activas;
- la verificación de salud y el documento de prueba usado para decidir la reversión;
- quién puede restaurar el conjunto de paquetes y la configuración anteriores.
Documentación heredada
El manual anterior traducido sigue disponible en Configuración heredada de .NET Standard. El Portal de integración anterior explica las mismas señales de identificación y enlaza de nuevo a esta guía de migración.
Mantenga la URL histórica en marcadores y tickets de soporte mientras existan instalaciones netstandard2.0. Documenta una generación diferente y no se redirige a la API actual.
¿Fue útil esta página?