Rychlý start

Vykreslete svůj první dokument v MVC 5 nebo Web Forms

Tento průvodce vezme aplikaci ASP.NET na .NET Framework 4.7.2 z nainstalovaného balíčku až k dokumentu vykreslenému v prohlížeči: Global.asax, otevřenému koncovému bodu, prostředkům prohlížeče, widgetu a tokenu, který je spojuje. Předpokládá, že registrace Web.config z Instalace jsou nastaveny — bez handleru DocImage.axd a modulů zdrojů nemůže nic níže dosáhnout na server.

Sestavte Doconut v Global.asax

Úplný Application_Start pro aplikaci MVC 5:

csharp
// Global.asax.cs - vytvořit jednou na pracovní proces, uvolnit při ukončení.
protected void Application_Start()
{
    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

    Doconut.DoconutHost.Initialize(options =>
    {
        options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
        options.UnsafeMode  = false; // stránka je podávána pouze relaci, která otevřela dokument
    });

    // Pouze MVC: udržet dva koncové body Doconut mimo routování.
    RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    RouteTable.Routes.IgnoreRoute("doconut-res/{*pathInfo}");
}

protected void Application_End()
{
    Doconut.DoconutHost.Shutdown();
}
  • Encoding.RegisterProvider zpřístupňuje procesům starší stránky s kódem, které některé formáty dokumentů používají. Zavolejte jej jednou, před otevřením prvního dokumentu.
  • UnsafeMode = false je výchozí nastavení, explicitně uvedené, aby ho nikdo neodškrtl náhodou: DocImage.axd slouží stránku pouze ASP.NET relaci, která dokument otevřela.
  • Dvě volání IgnoreRoute udržují MVC routování mimo DocImage.axd a /doconut-res/*, které obsluhují handler a modul. Aplikace Web Forms nemá MVC routy a nepotřebuje tento řádek.
  • DoconutHost.Shutdown zastavuje backgroundovou práci Doconut a uvolňuje jeho služby při recyklaci aplikačního poolu. Je bezpečné jej volat i když Initialize nikdy neběžel.

Otevřete dokument

Otevření dokumentu vrací neprůhledný token. Widget posílá tento token s každým požadavkem na stránku.

V MVC 5 akce kontroleru získá službu Viewer z DoconutHost.Services — MVC 5 nemá pro ni konstruktorovou injekci:

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

    // Token je neprůhledný - předávejte jej prohlížeči, nikdy jej nezaznamenávejte ani neukládejte.
    string token = await viewer.OpenDocumentAsync(Server.MapPath("~/files/Sample.pdf"));
    return Json(new { token });
}

Dokument musí být otevřen uvnitř požadavku, který má stav relace, protože jeho otevření umožňuje aktuální ASP.NET relaci přístup k jeho stránkám. Kontrolery MVC a stránky Web Forms mají stav relace ve výchozím nastavení. Vlastní IHttpHandler jej nemá, pokud neimplementuje System.Web.SessionState.IRequiresSessionState. Otevřete dokument z handleru bez něj a prohlížeč zobrazí na každé stránce „You Are Not Authorized To View This Page.“

V Web Forms může samotná stránka otevřít dokument ve svém code-behind. OpenDocument je synchronní forma OpenDocumentAsync, určená pro code-behind, který nepoužívá asynchronní stránky:

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"));
}

Token považujte za přístupové oprávnění: nikdy jej nezaznamenávejte ani neukládejte; předávejte jej pouze widgetu. Přestane fungovat, když vyprší relace dokumentu — otevřete dokument znovu, abyste získali nový.

Odkaz na prostředky prohlížeče

Viewer.ReferenceCss a Viewer.ReferenceScripts emitují značky <link> a <script> pro vložené prostředky, v pořadí závislostí, odkazující na /doconut-res/. Widget je jQuery plugin, takže jQuery přichází jako první.

MVC 5. Pohledy nemají @inject, takže vytvořte značky v kontroleru a předáte je pomocí 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)

Uchovejte tuto práci v kontroleru. MVC 5 kompiluje pohledy, když jsou poprvé podány, a bez extra balíčku kompilátoru tento kompilátor rozumí jen C# 5 — žádné ?., žádné $"...", žádné nameof. Pohled, který je používá, se v Visual Studio úspěšně zkompiluje a poté v prohlížeči vrátí prázdný 500.

Web Forms. Zveřejněte stejné řetězce z code-behind a zapište je pomocí <%= %>:

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

IncludeViewerCss a IncludeViewerScripts jsou povinné jádro. Pro přidání pásků Vyhledávání a Anotace nastavte také IncludeSearchCss, IncludeAnnotationCss, IncludeSearchScripts, IncludeSearchBar, IncludeAnnotationScripts a IncludeAnnotationBar. Obě metody vynechají soubory pásku, pokud licence tuto schopnost nepovoluje; samotný prohlížeč se stále spustí.

Přidání prohlížeče na stránku

Vykreslovací plocha jsou dva vnořené div:

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

Dejte vnějšímu div skutečnou výšku — prohlížeč vyplní svůj kontejner a změří jej při spuštění. Prohlížeč nevykresluje vlastní panel nástrojů: GotoPage, Next, Zoom, FitType a ostatní jsou metody, které vaše stránka připojuje k vlastním tlačítkům, umístěným vedle prohlížeče:

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>

Inicializace prohlížeče a zobrazení dokumentu

Po skriptech prohlížeče vytvořte widget a předáte mu token:

javascript
var objViewer = $('#div_ctlDoc').docViewer({
    showThumbs: true,
    autoLoad:   false,
    pageZoom:   100,
    FitType:    'width',
    BasePath:   '/',                   // '/' znamená DocImage.axd v kořenovém adresáři webu
    ResPath:    'doconut-res/images',  // žádný úvodní '/'
    onViewerReady: function () {
        // stránky jsou viditelné; zde skryjte indikátor načítání
    },
    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); });

Ve Web Forms, kde stránka sama otevřela dokument, poslední tři řádky se stanou objViewer.View('<%= Token %>');.

Čtyři podrobnosti zde selžou bez chybové zprávy:

  • BasePath: '/' odkazuje na DocImage.axd v kořeni webu. Pro aplikaci ve virtuálním adresáři použijte její název bez lomítek ('myapp' požaduje /myapp/DocImage.axd). Úvodní lomítko ('/myapp') vytváří //myapp/DocImage.axd, který prohlížeč interpretuje jako požadavek na jiný hostitel.
  • ResPath: 'doconut-res/images' — ikony jsou umístěny o jednu složku pod kořenem zdrojů. S 'doconut-res' každá ikona vrací 404: žádné glyphy panelu nástrojů a žádný načítací spinner, zatímco samotný dokument se stále vykresluje. Úvodní lomítko to rozbije stejným způsobem jako BasePath.
  • Callbacks jsou možnosti. onViewerReady, onError a ostatní patří do objektu předaného do docViewer(...). Globální funkce pojmenovaná po prohlížeči, jako je ctlDoc_ViewerReady, se nikdy nevolá.
  • Uchovejte prohlížeč a poté zavolejte View samostatně. docViewer(...) vrací objekt s Zoom, Next a FitType; View(...) vrací něco jiného. var objViewer = $('#div_ctlDoc').docViewer({...}).View(token) vykreslí dokument a poté selže s objViewer.Zoom is not a function při prvním kliknutí na panel nástrojů.

Názvy možností kombinují camelCase (showThumbs, autoLoad, pageZoom) a PascalCase (FitType, BasePath, ResPath). Nesprávně napsaná možnost je ignorována a widget použije výchozí hodnotu.

Jednořádková alternativa

Pro stránku, která potřebuje pouze zobrazit dokument a nemá vlastní panel nástrojů, Viewer.RenderViewer zapíše celý inicializační skript — docViewer(...) s BasePath: '/' a ResPath: 'doconut-res/images', pak .View(token). Vyskytuje se pouze v tomto balíčku:

csharp
// Web Forms code-behind, po otevření dokumentu
ViewerInit = viewer.RenderViewer("div_ctlDoc", Token);
html
<div id="div_ctlDoc" style="height: 100vh"></div>
<%= ViewerScripts %>
<%= ViewerInit %>

Předávejte ViewerConfig jako třetí argument pro změnu přiblížení, přizpůsobení nebo panelu miniatur. Protože vygenerovaný skript neuchovává žádnou referenci na prohlížeč, použijte výše uvedenou ručně psanou inicializaci, když vaše stránka potřebuje vlastní panel nástrojů.

Zavřít dokument

Zavolejte objViewer.Close(true), když uživatel opustí prohlížeč nebo otevře náhradu: vyčistí widget a odešle požadavek na zavření na DocImage.axd. objViewer.Close() bez argumentu vyčistí pouze widget. Na serveru viewer.CloseDocument(token) okamžitě odstraní relaci dokumentu, uvolní její vykreslovací prostředky a odebere relaci přístup k jejím stránkám. Posuvná expirace nakonec dělá totéž, ale explicitní uzavření velkých dokumentů uvolní paměť dříve.

Spusťte to

Umístěte PDF na ~/files/Sample.pdf, spusťte web v IIS Express (F5 ve Visual Studiu) a otevřete stránku, která hostuje widget. První stránka se vykreslí s miniaturami vlevo. Pokud se tak nestane, podívejte se na Řešení problémů.

Co získáte bez licence

Chybějící licence nevyvolá výjimku. Prohlížeč se vykresluje normálně, ale každá stránka nese vodoznak hodnocení. Viz Nastavení licence, kde Doconut hledá vaši licenci.

Byla tato stránka užitečná?