Snabbstart

Rendera ditt första dokument i MVC 5 eller Web Forms

Denna genomgång tar en ASP.NET-applikation på .NET Framework 4.7.2 från ett installerat paket till ett dokument som renderas i webbläsaren: Global.asax, en öppen slutpunkt, visningsens resurser, widgeten och token som kopplar dem. Den förutsätter att Web.config-registreringarna från Installation är på plats — utan DocImage.axd-hanteraren och resursmodulen kan inget nedan nå servern.

Komponera Doconut i Global.asax

En komplett Application_Start för en MVC 5-applikation:

csharp
// Global.asax.cs - compose once per worker process, release on shutdown.
protected void Application_Start()
{
    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

    Doconut.DoconutHost.Initialize(options =>
    {
        options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
        options.UnsafeMode  = false; // a page is served only to the session that opened the document
    });

    // MVC only: keep the two Doconut endpoints out of routing.
    RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    RouteTable.Routes.IgnoreRoute("doconut-res/{*pathInfo}");
}

protected void Application_End()
{
    Doconut.DoconutHost.Shutdown();
}
  • Encoding.RegisterProvider gör de äldre kodsidorna som vissa dokumentformat använder tillgängliga för processen. Anropa den en gång, innan det första dokumentet öppnas.
  • UnsafeMode = false är standardvärdet, skrivet ut så att ingen av misstag ändrar det: DocImage.axd levererar en sida endast till den ASP.NET-session som öppnade dokumentet.
  • De två IgnoreRoute-anropen håller MVC-routingen borta från DocImage.axd och /doconut-res/*, som hanteraren och modulen levererar. En Web Forms-applikation har ingen MVC-routing och behöver ingen av dessa rader.
  • DoconutHost.Shutdown stoppar Doconut's bakgrundsarbete och frigör dess tjänster när applikationspoolen återcirkuleras. Det är säkert att anropa även om Initialize aldrig kördes.

Öppna ett dokument

Att öppna ett dokument returnerar en opak token. Widgeten skickar den tokenen med varje sidförfrågan.

I MVC 5 löser en controller‑action Viewer-tjänsten från DoconutHost.Services — MVC 5 har ingen konstruktor‑injektion för den:

csharp
// POST /Document/Open
[HttpPost]
public async Task<ActionResult> Open()
{
    var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();

    // The token is opaque - hand it to the viewer, never log or persist it.
    string token = await viewer.OpenDocumentAsync(Server.MapPath("~/files/Sample.pdf"));
    return Json(new { token });
}

Dokumentet måste öppnas inom en begäran som har sessionsstate, eftersom öppnandet beviljar den aktuella ASP.NET-sessionen åtkomst till dess sidor. MVC‑controllers och Web Forms‑sidor har sessionsstate som standard. En anpassad IHttpHandler har det inte, såvida den inte implementerar System.Web.SessionState.IRequiresSessionState. Öppna ett dokument från en handler utan detta, och visaren visar "You Are Not Authorized To View This Page." på varje sida.

I Web Forms kan själva sidan öppna dokumentet i sin kod‑behind. OpenDocument är den synkrona formen av OpenDocumentAsync, avsedd för kod‑behind som inte använder asynkrona sidor:

csharp
// Default.aspx.cs
protected string Token;

protected void Page_Load(object sender, EventArgs e)
{
    var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
    Token = viewer.OpenDocument(Server.MapPath("~/files/Sample.pdf"));
}

Behandla tokenen som ett bärar‑credential: logga den aldrig eller lagra den; ge den endast till widgeten. Den slutar fungera när dokumentsessionen löper ut — öppna dokumentet igen för att få en ny.

Referera till visningsresurserna

Viewer.ReferenceCss och Viewer.ReferenceScripts genererar <link>- och <script>-taggarna för de inbäddade resurserna, i beroendeordning, pekande på /doconut-res/. Widgeten är ett jQuery‑plugin, så jQuery kommer först.

MVC 5. Vy‑filer har ingen @inject, så producera taggarna i kontrollern och skicka dem via ViewBag:

csharp
public ActionResult Index()
{
    var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
    ViewBag.ViewerCss = viewer.ReferenceCss(new CssConfig
    {
        IncludeBootstrapCss = true,
        IncludeViewerCss    = true
    });
    ViewBag.ViewerScripts = viewer.ReferenceScripts(new ScriptConfig
    {
        IncludeJQuery        = true,
        IncludeBootstrap     = true,
        IncludeViewerScripts = true
    });
    return View();
}
html
@Html.Raw(ViewBag.ViewerCss)
...
@Html.Raw(ViewBag.ViewerScripts)

Behåll det arbetet i kontrollern. MVC 5 kompilerar vyer när de först levereras, och utan ett extra kompilatorpaket förstår den bara C# 5 — ingen ?., ingen $"...", ingen nameof. En vy som använder dem kompileras utan problem i Visual Studio, men svarar med ett tomt 500 i webbläsaren.

Web Forms. Exponera samma strängar från kod‑bakom och skriv dem med <%= %>:

html
<head>
    <%= ViewerCss %>
</head>
<body>
    ...
    <%= ViewerScripts %>
</body>

IncludeViewerCss och IncludeViewerScripts är den obligatoriska kärnan. För att lägga till sök‑ och annoterings‑ribbons, sätt även IncludeSearchCss, IncludeAnnotationCss, IncludeSearchScripts, IncludeSearchBar, IncludeAnnotationScripts och IncludeAnnotationBar. Båda metoderna utelämnar en ribbons filer när licensen inte ger den möjligheten; själva visaren startar ändå.

Lägg till visaren på en sida

Renderingsytan är två nästlade div‑element:

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

Ge den yttre div:en en riktig höjd — visaren fyller sin behållare och mäter den när den startar. Visaren ritar inte sin egen verktygsrad: GotoPage, Next, Zoom, FitType och resten är metoder som din sida kopplar till sina egna knappar, placerade bredvid visaren:

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.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>
</nav>

Initiera visaren och visa dokumentet

Efter visarskriptet, skapa widgeten och ge den sedan token:

javascript
var objViewer = $('#div_ctlDoc').docViewer({
    showThumbs: true,
    autoLoad:   false,
    pageZoom:   100,
    FitType:    'width',
    BasePath:   '/',                   // '/' means DocImage.axd at the site root
    ResPath:    'doconut-res/images',  // no leading '/'
    onViewerReady: function () {
        // pages are visible; hide a loading indicator here
    },
    onError: function (message) {
        console.error('Doconut viewer error:', message);
    }
});

fetch('/Document/Open', { method: 'POST' })
    .then(function (resp) { return resp.json(); })
    .then(function (data) { objViewer.View(data.token); });

I Web Forms, där sidan öppnade dokumentet själv, blir de sista tre raderna objViewer.View('<%= Token %>');.

Fyra detaljer här misslyckas utan felmeddelande:

  • BasePath: '/' pekar på DocImage.axd i webbplatsens rot. För en applikation i en virtuell katalog, använd dess namn utan snedstreck ('myapp' begär /myapp/DocImage.axd). Ett inledande snedstreck ('/myapp') ger //myapp/DocImage.axd, vilket webbläsaren tolkar som en begäran till en annan värd.
  • ResPath: 'doconut-res/images' — ikonerna ligger en mapp under resursroten. Med 'doconut-res' returneras varje ikon med 404: inga verktygsradsglyfer och ingen laddningsindikator, medan själva dokumentet fortfarande renderas. Ett inledande snedstreck bryter det på samma sätt som BasePath.
  • Callback‑funktioner är alternativ. onViewerReady, onError och resten placeras i objektet som skickas till docViewer(...). En global funktion med samma namn som visaren, såsom ctlDoc_ViewerReady, anropas aldrig.
  • Behåll visaren och anropa sedan View separat. docViewer(...) returnerar objektet med Zoom, Next och FitType; View(...) returnerar något annat. var objViewer = $('#div_ctlDoc').docViewer({...}).View(token) renderar dokumentet, men misslyckas med objViewer.Zoom is not a function vid första klicket på verktygsraden.

Alternativnamnen blandar camelCase (showThumbs, autoLoad, pageZoom) och PascalCase (FitType, BasePath, ResPath). Ett felstavat alternativ ignoreras, och widgeten använder sitt standardvärde.

Enradigt alternativ

För en sida som bara behöver visa ett dokument, utan någon egen verktygsrad, Viewer.RenderViewer skriver hela initieringsskriptet — docViewer(...) med BasePath: '/' och ResPath: 'doconut-res/images', sedan .View(token). Det finns endast i detta paket:

csharp
// Web Forms code-behind, after opening the document
ViewerInit = viewer.RenderViewer("div_ctlDoc", Token);
html
<div id="div_ctlDoc" style="height: 100vh"></div>
<%= ViewerScripts %>
<%= ViewerInit %>

Skicka en ViewerConfig som det tredje argumentet för att ändra zoom, anpassning eller miniatyrpanelen. Eftersom det genererade skriptet inte behåller någon referens till visaren, använd den handskrivna initieringen ovan när din sida behöver en egen verktygsrad.

Stäng dokumentet

Anropa objViewer.Close(true) när användaren lämnar visaren eller öppnar en ersättare: den rensar widgeten och skickar en stängningsbegäran till DocImage.axd. objViewer.Close() utan argument rensar endast widgeten. På servern tar viewer.CloseDocument(token) bort dokumentsessionen omedelbart, frigör dess renderingsresurser och återkallar sessionens åtkomst till dess sidor. Glidande utgång gör så småningom samma sak, men att explicit stänga stora dokument frigör minnet tidigare.

Kör det

Placera en PDF på ~/files/Sample.pdf, starta webbplatsen i IIS Express (F5 i Visual Studio) och öppna sidan som innehåller widgeten. Den första sidan renderas, med miniatyrer till vänster. Om den inte gör det, se Felsökning.

Vad du får utan licens

En saknad licens ger inget fel. Visaren renderar normalt, men varje sida har ett utvärderingsvattenstämpel. Se Licensinställning för var Doconut letar efter din licens.

Var den här sidan hjälpsam?