Summary
This "How To" adds document viewing with page thumbnail navigation and full page view to an ASP.NET MVC 5 project. Additionally, add CORS for cross-domain requests to a web service hosted in IIS or IIS Express. The resulting project lays the foundation to add more advanced document functionality including text selection, annotation, bookmarks and conversion to an ASP.NET MVC application.
Objectives
- Setup the LEADTOOLS Documents Service in IIS.
- Configure Documents Service Host to support CORS.
- Add LEADTOOLS HTML5 DocumentViewer control to ASP.NET 4.5 MVC 5 project.
Overview
The HTML5 Document Viewer is a turnkey solution for viewing documents on any platform and device. The Document Viewer includes rich document features including text search, annotation, memory-efficient paging, inertial scrolling, scalable vector display, multi-page viewing, thumbnails and bookmarks. Additionally, the LEADTOOLS Document Viewer loads several document formats such as DOC, TIFF and PDF without additional third-party plugins.
The Leadtools.Documents.UI.DocumentViewer
control has the following parts:
- View: A required area of the control to view content of the document.
- Thumbnails: An optional area of the control to view thumbnails of the document pages.
- Bookmarks: An optional area of the control to view the bookmarks and table of content of the document.
- Annotations: An optional area of the control to display the annotations toolbar and objects list.
- Application User Interface: The rest are the UI elements of the user application and not part of the document viewer. Typically these are standard menu and toolbar items used to control the document viewer via commands.
The LEADTOOLS Document Viewer may be used in any HTML5 web project including ASP.NET MVC. The MVC paradigm separates an application into three main components: Model, View and Controller. The ASP.NET MVC framework integrates ASP.NET features such as master pages and authentication into MVC. Additionally, including the LEADTOOLS Document Viewer adds LEADTOOLS features such as display, conversion, annotation, image processing and OCR into MVC.
The controller part of the Document Viewer is the Documents Service. The Documents Service may be hosted in the same ASP.NET MVC application or as a separate service application for ubiquitous access. In order to host as a separate service application, the service host must support cross-origin resource sharing (CORS).
CORS is a standard mechanism that dictates access to restricted resources when requested from a different domain. A simplified example: a web page on site A posts an XMLHttpRequest
to a Web API hosted on site B. The client (CORS compliant browser) will first check with site B via an OPTIONS request to see if site B allows the request method and custom headers from site A’s domain. Section 6.2 of the W3C CORS standard calls this a preflight request. If site B does not allow the specified parameters in the OPTIONS request, then IIS returns a response with an HTTP status 405: Method not allowed.
Summary of Steps
- Step 1: Configure LEADTOOLS Documents Service in IIS
- Step 1 Alternate: Manually Configure LEADTOOLS Documents Service
- Step 2: Enable CORS in Global.asax
- Step 2 Alternate: Enable CORS in IIS via Web.config
- Step 3: Create an ASP.NET MVC Project
- Step 4: Add LEADTOOLS HTML 5 Document Viewer control to project
- Step 5: Add DocumentViewer View and Action
- Step 6: Update CSS
- Step 7: Run the project and test
All paths are based on the default LEADTOOLS installation folder (C:\LEADTOOLS 19) and may need to be adjusted based on the folder LEADTOOLS is installed.
Step 1: Configure LEADTOOLS Documents Service in IIS
The easiest way to configure the web services in IIS is to run the configuration utility in the C:\LEADTOOLS 19\Shortcuts\Document Viewer\JavaScript\ folder.
The configuration utility performs the following tasks:
- Create an application pool for the
DocumentsService
. - Create an application folder for the
DocumentsService
that points to the physical path: C:\LEADTOOLS 19\Examples\REST\DocumentsServiceHost and copies the selected .NET version of the LEADTOOLS DLLs to the bin folder. - Update the Web.config for the
DocumentsService
.
- Add supported mime types so IIS will serve files with those types of files.
- Create service endpoints.
- Add
appSettings
for LEADTOOLS license file path and developer key. - Add
appSettings
for LEADTOOLS cache settings as well as other LEADTOOLS settings for OCR and file conversion.
Step 1 Alternate: Manually Configure LEADTOOLS Documents Service
There are times when one will want to configure the Documents Service manually to have more control over the locations of files and name of the application folder or run the service host in IIS Express to test and debug. To configure the Documents Services manually, make sure that the .NET version for the application pool or website settings in Visual Studio matches the .NET version of LEADTOOLS copied to the host’s bin folder. If the x86 build of the LEADTOOLS assemblies are used then enable 32-bit applications in the application pool’s advanced settings must be set to true.
The source for the Documents Service host is in the C:\LEADTOOLS 19\Examples\REST\DocumentsServiceHost\ folder.
Copy the appropriate .NET version and bitness of the LEADTOOLS assemblies to the Documents Service Host Bin folder from the C:\LEADTOOLS 19\Redist\... folder.
Step 2: Enable CORS in Global.asax
If the source of the service host is available, then it is very easy to implement CORS support in the Global.asax file by handling the Application_BeginRequest()
event.
- Ensure the CORS headers are not being added in the Web.config. If they are, then a duplicate header exception will be thrown.
- Ensure that the OPTIONSVerbHandler is not first in the list of handlers. This is only needed when implementing CORS via Web.config only.
- Add a Global.asax file to the Documents Service Host project, if one does not already exist.
- Add the following code to the Global.asax for the
Application_BeginRequest()
event.
void Application_BeginRequest( object sender, EventArgs e )
{
var context = HttpContext.Current;
var response = context.Response;
// enable CORS
response.AddHeader( "Access-Control-Allow-Origin", "*" );
if ( context.Request.HttpMethod == "OPTIONS" )
{
response.AddHeader( "Access-Control-Allow-Methods", "GET, POST" );
response.AddHeader( "Access-Control-Allow-Headers",
"Content-Type, Accept" );
response.AddHeader( "Access-Control-Max-Age", "1728000" );
response.End();
}
}
If the Global.asax is not properly configured to support CORS from the calling domain, then IIS may return an HTTP status "405 – Method not allowed" on some service requests.
Step 2 Alternate: Enable CORS in IIS via Web.config
The Global.asax and Web.config methods should not be mixed. One method or the other should be used.
If the source code for the service is not available, then CORS may be implemented via Web.config only settings. Below is a truncated version of a Web.config file for the LEADTOOLS Documents Service Host. The config orders the handlers to move the OPTIONSVerbHandler before any other. This enables IIS to correctly handle the CORS preflight OPTIONS request that occurs during many cross-domain requests.
To move the OPTIONSVerbHandler to the top in the IIS Manager:
- Open the Handler Mappings of the Documents Service Host application folder.
- Tap the View Ordered List… in the Actions pane.
- Select the OPTIONSVerbHandler in the list of mappings and tap Move Up until the OPTIONSVerbHandler is first.
In addition, the Access-Control-Allow-Origin, Access-Control-Allow-Headers and Access-Control-Allow-Methods custom headers must be added to the Web.config.
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers"
value="content-type, accept" />
<add name="Access-Control-Allow-Methods" value="GET, POST" />
</customHeaders>
</httpProtocol>
<handlers>
<clear />
<add name="OPTIONSVerbHandler"
path="*"
verb="OPTIONS" type=""
modules="ProtocolSupportModule"
scriptProcessor=""
resourceType="Unspecified"
requireAccess="None"
allowPathInfo="false"
preCondition=""
responseBufferLimit="4194304" />
<add name="rules-64-ISAPI-2.0"
path="*.rules"
verb="*"
type=""
modules="IsapiModule"
resourceType="Unspecified"
requireAccess="Script"
allowPathInfo="false"
preCondition="classicMode,runtimeVersionv2.0,bitness64"
…
If these changes are not made, then IIS may return an "HTTP Status 405: Method not allowed" error when the Document Viewer or any application makes a request to the Documents Service Host located on a different domain or port than the requestor.
Step 3: Create an ASP.NET MVC Project
Once the LEADTOOLS Documents Service Host is setup up in either IIS or IIS Express, the next step is to create the ASP.NET MVC client project.
- In Visual Studio, create a new ASP.NET Web Application project.
- On the next screen, select the MVC template and click OK.
Once the project is created, add a couple of folders to the project. The project already contains a Scripts folder, but it is a good idea to create some additional folders for better code organization and management.
- Create a libs folder and js folder off the root of the project.
The libs folder is for third party TypeScript libs such as LEADTOOLS, Bootstrap and jQuery. The js folder is for application implementations.
Step 4: Add LEADTOOLS HTML5 Document Viewer control to Project
- Add existing item as link C:\LEADTOOLS 19\Examples\JS\Common\Libs\*.d.ts to project lib\leadtools folder.
- Add existing item as link C:\LEADTOOLS 19\Examples\JS\Common\Libs\bootstrap to project lib\bootstrap folder.
- Add existing item as link C:\LEADTOOLS 19\Examples\JS\Common\Libs\jquery to project lib\jquery folder.
Note that the items above are added to the project as linked items. This is to ensure that the relative paths defined in the TypeScript reference files are maintained. If the TypeScript declaration files are added directly to the project, then the reference paths in some of the files may need to be updated.
- Add existing items C:\LEADTOOLS 19\Examples\JS\Common\Libs\*.js to the project scripts folder.
- Add the following bundles code to the BundleConfig.cs file in the App_Start folder.
bundles.Add( new ScriptBundle( "~/bundles/leadtools" ).Include(
"~/scripts/Leadtools.js",
"~/scripts/Leadtools.Controls.js",
"~/scripts/Leadtools.Documents.js",
"~/scripts/Leadtools.*" ) );
bundles.Add( new ScriptBundle( "~/bundles/app" ).Include(
"~/js/app.js" ) );
The ASP.NET bundling mechanism combines and minimizes the JavaScript making it more efficient to load on the client.
The loading order of LEADTOOLS JavaScript files is important. The first three are explicitly listed to ensure that they are loaded in the correct order. The load order of the other files is not important so they are loaded with a wildcard.
Step 5: Add DocumentViewer View and Action
- Create a new view in Views>Home called
DocumentViewer
.
- Template – Empty (without model)
- Use the shared _Layout view.
- Replace the contents of the page with the following:
@{
ViewBag.Title = "Document Viewer";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="page-header">
<div class="row">
<div class="col-xs-12">
<div class="btn-group btn-group-xs pull-right" role="group">
<button type="button"
class="btn btn-primary"
id="interactiveCommand"
disabled>
Interactive.PanZoom
</button>
<button type="button"
id="interactiveDropDown"
class="btn btn-default dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul id="interactiveDropDownUL"
class="dropdown-menu pull-left"
role="menu"
aria-labelledby="dLabel">
</ul>
</div>
</div>
</div>
</div>
<div class="row no-gutter">
<div class="col-sm-2 col-md-2 col-lg-2">
<div id="thumbnails-container" class="thumbnails-container"></div>
</div>
<div class="col-sm-10 col-md-10 col-lg-10">
<div id="viewer-container" class="viewer-container"></div>
</div>
</div>
@section scripts {
<script
src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl( "~/bundles/leadtools" )">
</script>
<script
src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl( "~/bundles/app" )">
</script>
}
The thumbnails-container
and viewer-container
div tags are the placeholders for the thumbnails and view areas of the Document Viewer control.
The scripts
section references the LEADTOOLS and App bundles that were added in the BundleConfig.cs file.
- Update Controllers\HomeController.cs to add an
ActionResult
for the Document Viewer page.
public ActionResult DocumentViewer()
{
ViewBag.Message = "LEADTOOLS Document Viewer";
return View();
}
- Update Shared\_Layout.cshtml to add a navigation link to the Document Viewer page.
<li>@Html.ActionLink("Document Viewer", "DocumentViewer", "Home")</li>
- In the js folder, add a new TypeScript item called app.ts.
- Add the following code to the app.ts file.
module MVC5Demos {
export module DocumentViewerDemo {
export class DocumentViewerApp {
// holds instance of the document viewer control.
private documentViewer: lt.Documents.UI.DocumentViewer = null;
// initialize and load.
public run(): void {
var that = this;
// Set the location of the
lt.Documents.DocumentFactory.serviceHost = "http://localhost";
lt.Documents.DocumentFactory.serviceAppName =
"LEADTOOLSDocumentsServiceHost19";
lt.Documents.DocumentFactory.documentsServiceName =
"DocumentsService.svc";
// Init the document viewer, pass along the containers
var createOptions =
new lt.Documents.UI.DocumentViewerCreateOptions();
createOptions.viewContainer =
document.getElementById("viewer-container");
createOptions.thumbnailsContainer =
document.getElementById("thumbnails-container");
createOptions.useAnnotations = false;
// Create the document viewer
this.documentViewer =
lt.Documents.UI.DocumentViewerFactory.createDocumentViewer(
createOptions);
// We prefer SVG viewing
this.documentViewer.view.preferredItemType =
lt.Documents.UI.DocumentViewerItemType.svg;
// Load a PDF document
var url = "http://demo.leadtools.com/images/pdf/leadtools.pdf";
var loadDocumentCommand =
lt.Documents.LoadDocumentCommand.create(url);
loadDocumentCommand.run()
.done(function (document) {
// We have a document
// set the thumbnail size to max 80 x 80.
// Aspect is maintained.
document.images.thumbnailPixelSize =
lt.LeadSizeD.create(80, 80);
// Set the document in the viewer
that.documentViewer.setDocument(document);
})
.fail(function (error) {
alert("Error loading document: " + error)
});
}
}
}
}
var app = null;
$(document).ready(function () {
app = new MVC5Demos.DocumentViewerDemo.DocumentViewerApp();
app.run();
});
The app.run()
function is a barebones function to demonstrate how to initialize and load the DocumentViewer
control.
Step 6: Update CSS
The thumbnails and view div placeholders require the height attribute to be set in CSS, else the height will default to zero and the Thumbnails and View will not be seen.
- Add the following to the site.css file in the project content folder.
.viewer-container {
height: 470px;
}
.thumbnails-container {
height: 130px;
font-size: 8px;
}
@media (min-width: 768px) {
.viewer-container,
.thumbnails-container {
height: 600px;
}
}
The CSS uses the screen width via media query to dictate the width and height of the div containers. The app.ts implementation in the attached project changes the layout of the document viewer thumbnails and view based on the width of the thumbnails container.
Step 7: Run the Project and Test
- Run the project and click the Document Viewer link in the navigation menu.
The project will load http://demo.leadtools.com/images/pdf/leadtools.pdf.
Conclusion
LEADTOOLS provides developers with access to the world’s best performing and most stable imaging libraries in an easy-to-use, high-level programming interface for rapid development of business-critical applications.
The LEADTOOLS HTML5 Document Viewer control may be added to any web project in a similar fashion as ASP.NET MVC. This means advanced document viewer functionality may be added to virtually any web application.
For information concerning additional LEADTOOLS HTML5 features, check out these past articles.
Download Example Project
You can download the fully functional project which includes the features discussed above. To run this example you will need the following:
- Right click on the Solution and select "Enable NuGet Package Restore" before building.
- LEADTOOLS free 60 day evaluation
- Visual Studio 2012 with ASP.NET and Web Tools 2013.1, Visual Studio 2013 or later
- Browse to the LEADTOOLS Examples folder (e.g. C:\LEADTOOLS 19\Examples\) where you can find example projects for these and many more technologies in LEADTOOLS
Support
Do you need help getting up and going? Contact our support team for free technical support! For pricing or licensing questions, you can contact our sales team (sales@leadtools.com) or call us at +1-704-332-5532.