Γρήγορη Εκκίνηση

Αποδώστε το πρώτο σας έγγραφο σε λίγα λεπτά

Αυτός ο οδηγός μετατρέπει μια εφαρμογή ASP.NET Core από ένα κενό Program.cs σε ένα έγγραφο που αποδίδεται στον περιηγητή: καταχώρηση στον διακομιστή, το πλήρες πακέτο Viewer (εργαλειοθήκη Viewer, τοποθέτηση Viewer και προαιρετικές ταινίες Αναζήτησης/Σχόλιου), αναφορές πόρων, αρχικοποίηση πελάτη, άνοιγμα εγγράφου και εκτέλεση.

Ρύθμιση διακομιστή

AddDoconut() καταχωρεί τις υπηρεσίες· UseDoconutResources() και UseDoconut() συνδέουν το middleware. Η κλήση των πόρων πρέπει να γίνει πρώτη. Οι κλήσεις συνεδρίας είναι επίσης απαραίτητες — η προεπιλεγμένη ασφάλεια εγγράφων του Doconut επικυρώνει κάθε αίτημα σελίδας έναντι της κατάστασης συνεδρίας ASP.NET. Έχετε ήδη καταχωρήσει το Doconut κατά τη διάρκεια της Εγκατάστασης; Προχωρήστε στην επόμενη ενότητα.

csharp
builder.Services.AddDoconut(options =>
{
    options.LicensePath = "Doconut.Viewer.lic";
});
builder.Services.AddSession(); // Doconut document security rides on ASP.NET session state

app.UseSession();          // call UseSession() before UseDoconut()
app.UseDoconutResources(); // must be registered before UseDoconut()
app.UseDoconut();

Για μια διάταξη διαδρομών τύπου παραγωγής, αντιστοιχίστε το middleware εγγράφου σε έναν ρητό κλάδο και διατηρήστε τις τέσσερις ρυθμίσεις διαδρομής ευθυγραμμισμένες:

csharp
builder.Services.AddDoconut(options =>
{
    options.LicensePath = Path.Combine(AppContext.BaseDirectory, "Doconut.Viewer.lic");
    options.MiddlewarePath = "/doconut";
    options.ResourcesPath = "/doconut-res";
    options.UnsafeMode = false;
});
builder.Services.AddSession();

app.UseRouting();
app.UseSession();
app.UseDoconutResources();
app.Map("/doconut", branch => branch.UseDoconut());

MiddlewarePath είναι μια τιμή συντονισμού· δεν αντιστοιχίζει έναν κλάδο ASP.NET Core από μόνο του. Σε αυτό το παράδειγμα ο κεντρικός υπολογιστής αντιστοιχίζει το /doconut, έτσι ο πελάτης πρέπει να χρησιμοποιήσει BasePath: '/doconut'. Το ResourcesPath εξυπηρετεί το ενσωματωμένο πακέτο στο /doconut-res, και η διαδρομή πόρων εικόνας του widget είναι επομένως ResPath: '/doconut-res/images'.

Προσθήκη του viewer σε μια σελίδα

Το Viewer είναι ο απαιτούμενος πυρήνας της σελίδας. Η επιφάνεια απόδοσής του χρησιμοποιεί δύο ένθετα divs:

html
<div id="divDocViewer">
    <div id="div_ctlDoc"></div>
</div>

Θεωρήστε την εργαλειοθήκη, τις τοποθετήσεις των μονάδων και την επιφάνεια του Viewer ως μία σύνθεση σελίδας. Η Αναζήτηση και το Σχόλιο ενσωματώνουν τις ταινίες τους σε προαιρετικές τοποθετήσεις, αλλά αυτές οι μονάδες δεν είναι ποτέ αυτόνομες: συνδέονται πάντα με το Viewer στην ίδια σελίδα. Χρησιμοποιήστε την ίδια σειρά με τα Doconut.TestApp και Doconut.TestApp.Distributed:

html
<nav id="toolbar" aria-label="Document viewer controls">
    <!-- Viewer navigation, zoom, Search, and Annotation buttons -->
</nav>

<div id="searchBarMount"></div>
<div id="annBarMount"></div>

<div id="divDocViewer">
    <div id="div_ctlDoc"></div>
</div>

Αναφορά των πόρων του viewer

Σε μια Razor προβολή, η ενσωματωμένη υπηρεσία Viewer εκδίδει τις ετικέτες <link> και <script> του viewer με σειρά εξαρτήσεων — το widget είναι ένα πρόσθετο jQuery, επομένως το jQuery πρέπει να φορτωθεί πριν τα scripts του viewer:

html
@inject Doconut.Viewer Viewer

@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
    IncludeBootstrapCss = true,
    IncludeViewerCss    = true
}))

@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
    IncludeJQuery        = true,
    IncludeBootstrap     = true,
    IncludeViewerScripts = true
}))

Για το πλήρες πακέτο Viewer, ζητήστε μαζί τους πόρους του Viewer και των μονάδων:

html
@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
    IncludeBootstrapCss  = true,
    IncludeViewerCss     = true,
    IncludeSearchCss     = true,
    IncludeAnnotationCss = true
}))

@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
    IncludeJQuery             = true,
    IncludeBootstrap         = true,
    IncludeViewerScripts     = true,
    IncludeSearchScripts     = true,
    IncludeSearchBar         = true,
    IncludeAnnotationScripts = true,
    IncludeAnnotationBar     = true
}))

IncludeViewerCss και IncludeViewerScripts είναι οι υποχρεωτικές σημαίες πυρήνα. Ποτέ μην δημοσιεύετε ένα παράδειγμα ταινίας Αναζήτησης ή Σχολίου χωρίς αυτές, την τοποθέτηση Viewer και μια παρουσία docViewer. Τα ReferenceCss και ReferenceScripts παραλείπουν τους πόρους μιας προαιρετικής μονάδας όταν η τρέχουσα άδεια δεν παρέχει αυτή τη δυνατότητα· ο βασικός Viewer εξακολουθεί να ξεκινά.

Αρχικοποίηση του viewer

Το widget στην πλευρά του πελάτη είναι ένα πρόσθετο jQuery. Αυτό είναι ένα ελάχιστο σύνολο πραγματικών επιλογών αρχικοποίησης (όχι ψευδοκώδικας):

javascript
let searchBar = null;
let annBar = null;

const objViewer = $('#div_ctlDoc').docViewer({
    showThumbs: true,
    autoLoad:   false,
    pageZoom:   100,
    FitType:    'width',
    BasePath:   '/doconut',
    ResPath:    '/doconut-res/images',
    onViewerReady: function () {
        // pages are visible; safe to hide a loading spinner here
    },
    // Forward annotation lifecycle events to the embedded ribbon when it is present.
    onAnnLoaded:    () => annBar?.handleAnnLoaded(),
    onAnnSaved:     () => annBar?.handleAnnSaved(),
    onAnnSaveError: () => annBar?.handleAnnSaveError(),
    onAnnClosed:    () => annBar?.handleAnnClosed(),
    onError: function (message) {
        console.error('Doconut viewer error:', message);
    }
});

Η κεφαλαιοποίηση των επιλογών είναι πραγματικά ανάμεικτη — showThumbs, autoLoad και pageZoom είναι camelCase, ενώ FitType, BasePath και ResPath είναι PascalCase. Δεν υπάρχει συνεπής κανόνας· αν κάνετε λάθος στην κεφαλαιοποίηση, η επιλογή αγνοείται σιωπηρά (το widget επανέρχεται στην προεπιλογή του αντί να πετάξει σφάλμα).

Συναρμολόγηση του πλήρους πακέτου Viewer

Και οι δύο εφαρμογές αναφοράς .NET 8 εγκαθιστούν τα παρακάτω μέρη μαζί σε μία σελίδα:

Μέρος του πακέτουΑπαίτησηΠώς συνδέεται
Πόροι Viewer, τοποθέτηση και objViewerΑπαιτείταιΚύριος αποδότης εγγράφου
Εργαλειοθήκη ViewerΑπαιτείται στη σύνθεση αναφοράςΣήμανση κεντρικού υπολογιστή· τα κουμπιά καλούν το ίδιο objViewer
Ταινία ΑναζήτησηςΠροαιρετική, μονάδα με άδειαdoconutSearchBar(...).attach(objViewer)
Ταινία ΣχολίουΠροαιρετική, μονάδα με άδειαdoconutAnnotationBar(...).attach(objViewer)

Αν και η κύρια εργαλειοθήκη Viewer είναι σήμανση κεντρικού υπολογιστή, εγκαθίσταται μαζί με το Viewer και δεν πρέπει ποτέ να τεκμηριώνεται ως ανεξάρτητος έλεγχος. Αυτό διατηρεί τη διάταξη, τις ετικέτες, τα εικονίδια και τους κανόνες εξουσιοδότησης υπό τον έλεγχο της εφαρμογής σας, ενώ κάθε κουμπί ελέγχει την ίδια παρουσία Viewer:

html
<nav id="toolbar" aria-label="Document viewer controls">
    <button type="button" onclick="objViewer.GotoPage(1)">First</button>
    <button type="button" onclick="objViewer.Next(false)">Previous</button>
    <button type="button" onclick="objViewer.Next(true)">Next</button>
    <button type="button" onclick="objViewer.GotoPage(objViewer.TotalPages())">Last</button>
    <button type="button" onclick="objViewer.Zoom(false)">Zoom out</button>
    <button type="button" onclick="objViewer.Zoom(true)">Zoom in</button>
    <button type="button" onclick="objViewer.FitType('width')">Fit width</button>
    <button type="button" onclick="objViewer.FitType('height')">Fit height</button>
    <button type="button" id="openSearch">Search</button>
    <button type="button" id="openAnnotations">Annotations</button>
</nav>

Η πλήρης εργαλειοθήκη αναφοράς αντιγράφει επίσης το wwwroot/js/viewerToolbar.js στην εφαρμογή κεντρικού υπολογιστή για βοηθητικά προγράμματα περιστροφής, μικρογραφιών, εκτύπωσης, πλήρους οθής, διάταξης και κατάστασης κουμπιών. Φορτώστε αυτό το αρχείο κεντρικού υπολογιστή μετά το Viewer.ReferenceScripts(...). Διατηρήστε τον βοηθό και τη σήμανση <nav id="toolbar"> μαζί όταν αντιγράφετε την πλήρη υλοποίηση επίδειξης.

Διατηρήστε τη σειρά αρχικοποίησης του πακέτου που χρησιμοποιούν και οι δύο εφαρμογές αναφοράς:

  1. Εκδώστε μαζί τους πόρους Viewer, Αναζήτησης και Σχολίου.
  2. Αποδώστε μαζί την εργαλειοθήκη Viewer, τις τοποθετήσεις Ribbon και την τοποθέτηση Viewer.
  3. Αρχικοποιήστε πρώτα το docViewer.
  4. Δημιουργήστε κάθε άδεια Ribbon και συνδέστε το με το ίδιο objViewer.
  5. Ανοίξτε το έγγραφο και διατηρήστε το token του για αιτήματα μονάδων.

Doconut.TestApp.Distributed διατηρεί αυτήν την ακριβή σύνθεση UI και τον ίδιο βοηθό εργαλειοθήκης Viewer. Η πρόσθετη τιμή αιτήματος access και οι ρυθμίσεις επανάληψης ασύγχρονης απόδοσης ανήκουν στη διανεμημένη μεταφορά· δεν αλλάζουν τον τρόπο συναρμολόγησης του Viewer, της εργαλειοθήκης ή των Ribbons.

Οι έλεγχοι στην πλευρά του διακομιστή είναι σημαντικοί: όταν μια προαιρετική δυνατότητα δεν είναι διαθέσιμη, το script της δεν εκδίδεται, έτσι η λειτουργία του jQuery plug-in δεν υπάρχει.

Και τα δύο ενσωματωμένα στοιχεία δημιουργούν το δικό τους DOM Ribbon. Η Αναζήτηση περιλαμβάνει ομάδες Find, Options και Results. Το Σχόλιο περιλαμβάνει τα εργαλεία συγγραφής, τους ελέγχους στυλ, τις ενέργειες αποθήκευσης και τις προαιρετικές ενέργειες εξαγωγής/εικόνας. Οι μπαρ εκθέτουν open(), close(), reset() και isOpen()· πάντα καλέστε attach(objViewer) μία φορά μετά τη δημιουργία τους.

Το παραπάνω παράδειγμα παραλείπει προαιρετικές κλήσεις επιστροφής κεντρικού υπολογιστή και τα σημεία λήψης εξαγωγής/εικόνας Σχολίου για να διατηρήσει την εκκίνηση ελάχιστη. Δείτε την Αναζήτηση και τα Σχόλια για τη πλήρη ρύθμιση συγκεκριμένων λειτουργιών, ή τα Προσαρμοσμένα Θέματα για να μορφοποιήσετε ή να αντικαταστήσετε την εργαλειοθήκη Viewer που ανήκει στον κεντρικό υπολογιστή.

Άνοιγμα εγγράφου

Η πλευρά του διακομιστή είναι ένα σημείο λήψης: η ενσωματωμένη υπηρεσία Viewer ανοίγει το έγγραφο και επιστρέφει ένα token συνεδρίας.

csharp
app.MapPost("/api/open", async (Viewer viewer) =>
{
    // The token is opaque — hand it to the widget, never log or persist it.
    string token = await viewer.OpenDocumentAsync("wwwroot/files/Sample.pdf");
    return Results.Ok(new { token });
});

Ο πελάτης λαμβάνει αυτό το token και το παραδίδει στο widget με objViewer.View(token):

javascript
fetch('/api/open', { method: 'POST' })
    .then(resp => resp.json())
    .then(data => {
        currentToken = data.token;
        objViewer.View(currentToken);
    });

Κλείσιμο του εγγράφου

Καλέστε objViewer.Close() όταν ο χρήστης αφήνει το viewer ή ανοίγει ένα αντικατάστατο έγγραφο. Σε ροές εργασίας που ελέγχονται από τον διακομιστή, το viewer.CloseDocument(token) αφαιρεί αμέσως τη cached συνεδρία, απελευθερώνει τη μηχανή απόδοσης, διαγράφει το δείκτη ασφαλείας του και ανακαλεί το token. Η κυλιόμενη λήξη τελικά εκτελεί την ίδια εκκαθάριση, αλλά η ρητή κλείσιμο συνιστάται για μεγάλα έγγραφα.

Η ολοκληρωμένη ροή αιτήματος είναι:

text
AddDoconut + middleware
    -> render CSS/scripts and mount div
    -> initialize docViewer
    -> OpenDocumentAsync
    -> return opaque token
    -> objViewer.View(token)
    -> page/search/annotation requests
    -> Close / CloseDocument

Αντιμετωπίστε το token όπως ένα διακριτικό πρόσβασης: μην το καταγράφετε ποτέ, μην το αποθηκεύετε ποτέ, παραδώστε το μόνο στο widget. Αναγνωρίζει μια ενεργή συνεδρία εγγράφου στον διακομιστή και σταματά να λειτουργεί όταν η συνεδρία λήξει — ανοίξτε ξανά το έγγραφο για να λάβετε ένα νέο.

Εκτέλεση

Τοποθετήστε ένα PDF στο wwwroot/files/Sample.pdf, εκτελέστε dotnet run και ανοίξτε τη σελίδα που φιλοξενεί το widget. Η πρώτη σελίδα αποδίδεται στο viewer, με ένα πάνελ μικρογραφιών στα αριστερά. Αν δεν συμβεί, δείτε την Αντιμετώπιση προβλημάτων.

Τι λαμβάνετε χωρίς άδεια

Μια ελλιπής άδεια δεν προκαλεί σφάλμα. Ο viewer αποδίδει κανονικά, αλλά κάθε σελίδα φέρει ένα υδατογράφημα αξιολόγησης. Δείτε τη Ρύθμιση Άδειας για το πώς το Doconut βρίσκει μια άδεια και τι αλλάζει όταν το κάνει.

Ήταν αυτή η σελίδα χρήσιμη;