Viewer
The main document viewer class
Viewer (namespace Doconut) is the public entry point for opening documents from MVC controllers, Web Forms pages, and handlers. It is a transient service composed by DoconutHost.Initialize; resolve it where you use it:
var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();new Viewer() also works once DoconutHost.Initialize has run — it resolves the same services — which keeps code migrated from the classic package compiling. Before Initialize, it throws InvalidOperationException.
Viewer holds no per-request document state and intentionally does not implement IDisposable: document sessions live independently of it, so disposing a Viewer could never close an open document (see How the Viewer Works).
OpenDocumentAsync
Opens a document and returns the session token the widget uses for every later request. When UnsafeMode is false (the default), the token is granted to the ASP.NET session of the current request — call it from a request that has session state (see Sessions & Security).
| Overload | Use when |
|---|---|
Task<string> OpenDocumentAsync(string filePath, DocOptions? options = null, CancellationToken ct = default) | Opening from disk with automatic format detection and the format's default config |
Task<string> OpenDocumentAsync(string filePath, BaseConfig? config, DocOptions? options = null, CancellationToken ct = default) | You need per-format rendering options (PdfConfig, WordConfig, …) |
Task<string> OpenDocumentAsync(Stream stream, FileInfo fileInfo, BaseConfig? config = null, DocOptions? options = null, CancellationToken ct = default) | The document isn't a file on disk (an upload, a database, a blob). fileInfo must carry the right extension — it selects the format |
// Simple open
string token = await viewer.OpenDocumentAsync(path);
// With per-format config and options
token = await viewer.OpenDocumentAsync(
path,
new PdfConfig { AllowSearch = true, AllowCopy = true },
new DocOptions { TimeOut = 30 });
// From an upload (HttpPostedFileBase in MVC; HttpPostedFile in Web Forms)
using (var ms = new MemoryStream())
{
await file.InputStream.CopyToAsync(ms);
ms.Position = 0;
token = await viewer.OpenDocumentAsync(ms, new FileInfo(Path.GetFileName(file.FileName)));
}Exceptions to handle:
LicenseException— a license was found but rejected (the message carries the reason), or the format needs a plugin capability the license does not grant.FormatNotSupportedException— no viewer handles the file's extension.InvalidDataException— the content is corrupt or does not match its extension.
OpenDocument (synchronous)
For Web Forms code-behind and other code that does not use asynchronous pages:
string OpenDocument(string filePath, BaseConfig? config = null, DocOptions? options = null)
string OpenDocument(Stream stream, string fileName, BaseConfig? config = null, DocOptions? options = null)
string OpenDocument(byte[] bytes, string fileName, BaseConfig? config = null, DocOptions? options = null)Each returns the token and also stores it in viewer.Token. fileName must carry the right extension. These wrappers are safe to call from a Web Forms page: the open path never resumes on the ASP.NET request context, so waiting on it cannot deadlock. The same is not true of every asynchronous Doconut API — see the Web Forms section of Converter Plugin.
CloseDocument
void CloseDocument(string token)Removes the session (releasing the document engine immediately), removes the token's grant from the current request's ASP.NET session, and revokes the token. Optional — sliding expiration performs the same cleanup — but recommended for large documents.
Session queries
| Member | Returns |
|---|---|
int GetPageCount(string token) | Total pages of the open document |
(int Width, int Height) GetPageDimensions(string token, int page = 1) | Default rendered page size at 100% zoom — the coordinate space for annotations built in code |
IReadOnlyList<string> GetWorksheetNames(string token) | A spreadsheet's rendered worksheets, in workbook order; empty for other documents |
Each throws if the token is unknown or expired.
DocOptions
Per-open, format-independent options (namespace Doconut):
| Type | Property | Default | Description |
|---|---|---|---|
string | Password | "" | Password for protected documents (copied into the format config automatically). |
string | Watermark | "" | Custom watermark text drawn on rendered pages — see below. |
int | TimeOut | 60 | Session sliding expiration, in minutes. |
string | BrowserId | "" | Web farms: the browser a signed ticket is bound to. Set it with DoconutFarmBinding.EnsureBrowserId (see Sessions & Security). |
string | UserId | "" | Web farms: the signed-in user a ticket is bound to, from DoconutFarmBinding.ResolveUserId. |
int | ImageResolution | 0 | Obsolete. Set ImageResolution on the format config instead. |
bool | IsSecured | true | Reserved; not enforced. Access control is DoconutOptions.UnsafeMode. |
bool | IsWebFarm / string WebFarmPath | false / "" | Kept for code migrated from the classic package. They do not switch farm mode on — AddDoconutDistributed does. |
bool | EditMode | false | Reserved for the separately distributed editor; leave false. |
Custom watermark
DocOptions.Watermark takes six tilde-separated fields. An optional leading ^ requests the all-corners layout:
^Text~Color~FontSize~FontName~Opacity~Anglestring token = await viewer.OpenDocumentAsync(
path,
new PdfConfig(),
new DocOptions
{
Watermark = "^Confidential~Red~24~Verdana~80~-45",
TimeOut = 30
});| Field | Example | Meaning |
|---|---|---|
Leading ^ | ^ | Optional all-corners layout. Without it, the normal placement is used. |
| Text | Confidential | Text drawn on each page. It must not be empty. |
| Color | Red | A named color. |
| FontSize | 24 | Font size; invalid numeric input falls back to the default. |
| FontName | Verdana | Font family. It must be installed on the server — Windows Server has fewer fonts than a desktop. |
| Opacity | 80 | 0 to 255. It must parse. |
| Angle | -45 | Rotation in degrees; invalid numeric input falls back to the default. |
The parser expects exactly six fields after the optional ^. An invalid definition is replaced by a visible Invalid Watermark text instead of silently disappearing.
License decision
| License state | Custom value supplied | Rendered result |
|---|---|---|
| Valid paid viewer license | No | Clean page |
| Valid paid viewer license | Yes | Custom watermark |
| Active Temporary/Demo license | No | Clean page |
| Active Temporary/Demo license | Yes | Custom watermark |
| Missing, rejected, expired, wrong-version, or invalid-domain license | Either | Evaluation watermark; the custom value does not replace it |
The same decision applies to served pages and to annotation exports. A custom watermark is a feature of a licensed application, not a way to replace the evaluation watermark.
Annotations API
Server-side annotation loading and export. The walkthrough is in Annotations.
| Member | Purpose |
|---|---|
AnnotationManager GetAnnotationManager(string token) | Manager bound to the open session's page dimensions |
AnnotationManager GetAnnotationManager(string token, int pageWidth, int pageHeight) | Manager with explicit page dimensions |
AnnotationManager GetAnnotationManager(int pageWidth, int pageHeight) | Session-independent manager |
void LoadAnnotationData(string token, AnnotationManager manager) | Load annotations built in C# into the session |
void LoadAnnotationData(string token, string annotationData) | Load the encoded envelope returned by AnnotationManager.GetAnnotationData() |
void LoadAnnotationXML(string token, XmlDocument annotationXml) | Load annotations from XML |
XmlDocument GetAnnotationXML(string token) | Export the session's annotations as XML |
Task<byte[]> ExportAnnotationsToPdfAsync(string token, int zoom = 100, CancellationToken ct = default) | PDF with annotations burned in |
Task<int> ExportAnnotationsToPngAsync(…) | PNG files with annotations burned in |
Task<byte[]> ExportAnnotationsToPngZipAsync(string token, int zoom = 100, CancellationToken ct = default) | ZIP of per-page PNGs with annotations burned in |
DICOM metadata
Task<DicomMetadata?> GetDicomMetadataAsync(string token, CancellationToken ct = default)On this package it always returns null, and the widget's metadata request answers 501 Not Implemented: reading DICOM tags is not available on .NET Framework. DICOM rendering — pages, frames, and animation — works. See DICOM Plugin.
Resource helpers — ReferenceCss / ReferenceScripts
Emit the <link> and <script> tags for the resources the resource module serves under DoconutOptions.ResourcesPath, in dependency order. The files for license-gated features (Search, Annotation) are emitted only when the license grants them.
string ReferenceCss(CssConfig? config = null) // null → Bootstrap + viewer + search + annotation
string ReferenceScripts(ScriptConfig? config = null)
bool IsSearchEnabled { get; } // license state, for guarding ribbon init code
bool IsAnnotationEnabled { get; }CssConfig flags: IncludeBootstrapCss, IncludeViewerCss, IncludeSearchCss (search-gated), IncludeAnnotationCss (annotation-gated).
ScriptConfig flags: IncludeJQuery (required by all others), IncludeBootstrap, IncludeViewerScripts (the core viewer scripts), IncludeSearchScripts and IncludeSearchBar (search-gated), IncludeAnnotationScripts and IncludeAnnotationBar (annotation-gated).
Both return HTML: write them with @Html.Raw(...) in MVC 5 (produce them in the controller — views have no @inject) or <%= %> in Web Forms. Quick Start shows both.
RenderViewer
string RenderViewer(string elementId, string token, ViewerConfig? config = null)Returns a <script> block that initialises the widget on the element with id elementId and shows the document: docViewer({...}) built from the ViewerConfig (default: BasePath: '/', ResPath: 'doconut-res/images'), then .View(token). Write it after the viewer scripts. The generated script keeps no reference to the viewer object, so a page with its own toolbar should initialise the widget by hand instead. See ViewerConfig.
Web farm
string? AccessToken holds the signed ticket issued by the most recent open when distributed mode is active and UnsafeMode is false; it is null on a single server. Send it to the widget with the token: objViewer.View(token, access).
Apakah halaman ini membantu?