Migrazione

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

Questa pagina tratta l'aggiornamento di un'applicazione ASP.NET esistente da Doconut.NETFramework 26.8.0 o versioni precedenti (.NET Framework 4.7) a 26.9.0 e successive (.NET Framework 4.7.2). Il pacchetto di esempi Doconut contiene la guida completa alla migrazione e gli esempi classici portati alla nuova API — MVC 5, una web farm e Web Forms. Confrontare la tua applicazione con l'esempio da cui è partita è il percorso più veloce.

Un pacchetto, due versioni

Entrambe le librerie vengono pubblicate con lo stesso ID pacchetto, Doconut.NETFramework. La versione le distingue:

VersioneDestinazioneAPI
26.8.0 e precedenti.NET Framework 4.7l'API precedente
26.9.0 e successive.NET Framework 4.7.2la nuova API

L'aggiornamento del pacchetto è l'upgrade. Non esiste un pacchetto separato da installare né uno strato di compatibilità: 26.9.0 ha una superficie API diversa, quindi attenditi errori di compilazione dopo l'aggiornamento — il resto di questa pagina. La linea .NET Framework 4.7 è stata interrotta e 26.8.0 è l'ultima sua release. Puoi rimanere su di essa — nulla qui è una correzione di sicurezza che ti manchi — ma le nuove versioni, i plugin, la modalità distribuita e i widget integrati arrivano solo su 26.9.0 e successive.

1. Reindirizzare e aggiornare il pacchetto

Reindirizza prima il progetto web a .NET Framework 4.7.2: un progetto che ancora punta a 4.7 non può installare 26.9.0, e NuGet rifiuta l'aggiornamento. Poi aggiorna Doconut.NETFramework e aggiungi i pacchetti plugin che utilizzi (Doconut.NETFramework.Converter, Doconut.NETFramework.Dicom, …). Ogni plugin richiede una licenza che lo conceda.

Se il progetto utilizza packages.config, l'aggiornamento esegue la fase di disinstallazione della versione precedente, che rimuove il gestore DocImage da Web.config, e 26.9.0 non lo reinserisce. Registralo nuovamente come mostrato al passo 3; finché non lo fai, DocImage.axd restituisce 404 e nessuna pagina viene renderizzata.

2. Spazi dei nomi: quasi tutto spostato nella radice

PrimaOra
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;invariato

I nomi dei tipi non sono cambiati: WordConfig, PdfConfig, ExcelConfig, CssConfig, ScriptConfig, FileShareConfig e il resto è ancora presente. Nella maggior parte dei file l'intera modifica consiste nell'eliminare le righe using.

3. Avvio: DoconutHost.Initialize e due voci di Web.config

Il pacchetto classico costruiva il suo visualizzatore per richiesta, con le opzioni come proprietà di quell'istanza. Il nuovo pacchetto ha una radice di composizione, costruita una volta in Application_Start, e il visualizzatore è un servizio che risolvi:

csharp
// Prima - Doconut.NETFramework 26.8.0 e precedenti, su richiesta
var viewer = new Viewer
{
    ID = "ctlDoc",
    IncludeJQuery = true,
    BasePath = "/",
    FitType = "width"
};
csharp
// Doconut.NETFramework 26.9.0\u002B - Viewer risolto da DoconutHost, licenza configurata una volta in DoconutHost.Initialize()
var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
var token  = await viewer.OpenDocumentAsync(path, new PdfConfig { AllowSearch = true });

DoconutHost.Initialize va in Application_Start e DoconutHost.Shutdown in Application_End, e Web.config ottiene il gestore DocImage.axd e il modulo risorsa — entrambi sono in Installation. Le impostazioni di aspetto per pagina (FitType, FixedZoom, ShowHyperlinks, …) sono state spostate dall'istanza del visualizzatore alle opzioni del widget, o a un ViewerConfig passato a Viewer.RenderViewer (vedi ViewerConfig). new Viewer() compila ancora una volta che DoconutHost.Initialize è stato eseguito, così il code-behind migrato può mantenere quella riga mentre sposti le impostazioni.

La sicurezza funziona come prima. Aprire un documento concede alla sessione ASP.NET corrente l'accesso alle sue pagine, e DocImage.axd nega a tutti gli altri. L'impostazione app DoconutUnSafeMode che disattivava questa funzionalità è ora options.UnsafeMode in DoconutHost.Initialize — lasciala false. Vedi Sessions & Security.

Il fallimento di avvio che blocca l'intero sito. Un plugin registrato la cui capacità non è concessa da alcuna licenza genera un'eccezione in Application_Start, e l'applicazione risponde quindi con un 500 vuoto a ogni richiesta — nessuna pagina di errore, nulla nel log IIS, solo una voce nel registro eventi di Windows (origine ASP.NET). Le licenze sono lette da wwwroot sotto la radice del sito e da nessun'altra parte, e il Doconut.Viewer.lic di base deve essere presente altrimenti le licenze del plugin accanto non vengono lette. Vedi License Setup.

4. Web farm: da un flag alla modalità distribuita

Il modello classico era viewer.IsWebfarm = true più ExportToPng(path). Il nuovo modello è registrato una sola volta: ogni nodo condivide un archivio e una chiave di firma, e un ticket firmato legato al browser sostituisce "whichever node answers":

csharp
Doconut.DoconutHost.Initialize(
    options => options.UnsafeMode = false,
    services => services.AddDoconutDistributed(d =>
    {
        d.Store             = CloudLocation.FileShare;
        d.FileShareRootPath = @"\\fileserver\doconut-shared";   // WebfarmPath è un alias
        d.SigningKey        = farmKey;                           // >= 32 byte, lo stesso su ogni nodo
    }));

Quindi apri i documenti normalmente, collegando il browser (DocOptions.BrowserId = DoconutFarmBinding.EnsureBrowserId(...)) e passando viewer.AccessToken al widget con il token. Sessioni e Sicurezza ha i passaggi; l'esempio web-farm è un nodo completo. IsWebfarm e WebfarmPath compilano ancora, ma non attivano più nulla.

Due cose che sembrano un successo ma non lo sono: DistributedDocumentPublisher.PublishAsync scrive i file renderizzati di un documento ma non apre alcuna sessione, quindi un visualizzatore puntato a un token pubblicato ottiene l'immagine di errore di ~2 KB con stato 200; e un client di test senza il cookie doconut-client ottiene la stessa immagine, non un 401. Distinguere una pagina reale dall'immagine di errore per dimensione.

5. La conversione è un plugin, e molto più piccola

L'enum SourceFormatConverter, le dodici classi *ConfigConverter e i loro enum target nidificati sono sostituiti da un enum, ConversionTarget, e una chiamata:

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

// Assumi che DoconutHost sia già inizializzato e che un CancellationToken chiamato ct sia disponibile.
var provider = DoconutHost.Services;
var converter = (DocumentConverter)provider.GetService(typeof(DocumentConverter));
Stream source = /* il tuo flusso di input */;
var result = await converter.ConvertAsync(source, ".dwg", ConversionTarget.Pdf, null, ct);

Il formato sorgente proviene dall'estensione che passi. Non esiste un shim di compatibilità: ogni riferimento SourceFormatConverter è un errore di compilazione che risolvi eliminandolo. Gli oggetti opzione per formato non sono sopravvissuti — WordConfigConverter.HtmlOptions e CadConfigConverter.CadOptions.ShowColor non hanno equivalenti tramite ConvertAsync. In Web Forms, non bloccare mai ConvertAsync — vedi Plugin di conversione.

6. Archiviazione cloud: accedila come cartella condivisa

I tipi di configurazione cloud sono stati spostati su Doconut.Clouds invariati. I gestori di richieste cloud, tuttavia, sono componenti ASP.NET Core, e un'applicazione classica non ha una pipeline in cui eseguirli. Da un sito System.Web, accedi all'archiviazione cloud come una cartella condivisa — su Azure, una condivisione Azure Files montata su ogni nodo — indirizzata tramite FileShareConfig.

7. Le modifiche lato client che falliscono silenziosamente

Ogni elemento qui sotto compila, esegue, non registra nulla e fa la cosa sbagliata:

PrimaOra
ResPath: 'doconut-res'ResPath: 'doconut-res/images' — altrimenti ogni icona restituisce 404 mentre il documento viene renderizzato
function ctlDoc_ViewerReady() { }docViewer({ onViewerReady: function () { } }) — le callback del visualizzatore sono ora opzioni
var viewer = $(el).docViewer({...}).View(token)Assegna prima docViewer(...), poi chiama viewer.View(token) separatamente
viewer.Refit() per adattare a una paginaviewer.FitType('width') — Refit() ricalcola solo il layout
var n = viewer.Search(kw, exact)viewer.Search(kw, exact, function (n) { … }) — il conteggio arriva nella callback
if (viewer.SaveAnnotations()) { … }docViewer({ onAnnSaved: …, onAnnSaveError: … })
function ctlDoc_Created() { } (annotazioni)Invariato — le funzioni evento di annotazione sono ancora globali, trovate per nome

Tre altri: il visualizzatore non disegna la sua barra degli strumenti (la tua pagina collega Zoom, Next, GotoPage e il resto ai propri pulsanti); un visualizzatore creato all'interno di un modal Bootstrap nascosto misura 0×0 e non disegna nulla finché non assegni al suo contenitore un'altezza esplicita e lo ridimensioni su shown.bs.modal; e AllowSearch predefinito è false per PDF, quindi un documento viene renderizzato perfettamente mentre ogni ricerca non restituisce nulla.

8. Cosa scompare

SparitoAl posto
DocumentSearch / TextSearch.csNiente — la ricerca funziona sul testo estratto dai visualizzatori di formato
Viewer.WatermarkInfoNessun equivalente
WordConfigConverter.HtmlOptionsNessun oggetto opzione tramite ConvertAsync
SourceFormatConverter, le classi *ConfigConverterConversionTarget e ConvertAsync
Doconut.Configs.EditorRimosso
viewer.IsWebfarm + ExportToPng(path)AddDoconutDistributed e apertura ordinaria

Ordine di lavoro suggerito

  1. Ririvolgere, scambiare il pacchetto e far compilare Global.asax con DoconutHost.Initialize e le due registrazioni Web.config. Il sito dovrebbe avviarsi.
  2. Una pagina visualizzatore: ottenere un documento da renderizzare, poi procedere attraverso la sezione 7 finché la barra degli strumenti, la ricerca e le annotazioni funzionano. Verifica in un browser reale — nulla in quella sezione genera errori.
  3. Conversione (sezione 5): meccanica, e la maggior parte degli errori di compilazione.
  4. Le pagine rimanenti, usando i campioni portati come target di differenza.
  5. Il web farm (sezione 4), se ne hai uno. Testa con due nodi e un browser, o un client che conserva i cookie.

Questa pagina è stata utile?