DocuVieware Reference Guide
DocuVieware integration in .NET Core web application
Tutorials > ASP.NET Core > DocuVieware integration in .NET Core web application
 Overview

This tutorial will show you how to integrate DocuVieware™ in a newly created C# .NET Core MVC Web Application project with Razor view engine.

This tutorial has been done using .NET Core 2.0, other versions will most probably differ.
DocuVieware™ requires .NET Framework 4.6 or above.
The screenshots have been taken using Visual Studio 2017 and GdPicture.NET™ 14, it may differ from the current release.

Summary

 Empty project creation

Start with the File > New > Project... menu, then in Visual C# choose .NET Core > ASP.NET Core Web Application. In this tutorial you will be working on DocuViewareNetCore which is a new ASP.NET Core MVC project.

Make sure to target the application to .NET Framework as shown on the screeshot below.

Here is the structure obtained:

Now that the project structure is ready, the next step will be to add project references.

 Adding mandatory referencies
 DocuVieware references and prerequisites

Step 1: The first reference to add is GdPicture.NET.14.WEB.DocuVieware.dll that is found in [INSTALLATION FOLDER]\Redist\DocuVieware\.

Step 2: It is required to also add a reference to System.Web that is part of the .NET Framework.

Step 3: You also need to add the Microsoft.AspNetCore.Mvc.WebApiCompatShim NuGet package to enable ASP.NET Web API support in .NET Core.

 Additional resources

You also need to add DocuVieware™ own JavaScript and CSS to the project, docuvieware-min.js and docuvieware-min.css, both found in [INSTALLATION FOLDER]\Redist\DocuVieware (Resources)\, simply add them to the css and js folders of the project.

 Setting up licensing

Now that the references are properly set, you need to go to the Startup.cs file of the project to add some mandatory imports and handle the DocuVieware™ licensing part as well.

using System.Web;
using GdPicture14.WEB;

To properly unlock DocuVieware™ you are going to add a call to the RegisterKEY method in the Configure method that is called on runtime.

// DocuVieware Core Configuration
DocuViewareManager.SetupConfiguration(true, DocuViewareSessionStateMode.File, Path.Combine(Directory.GetCurrentDirectory(), "Cache"), "/", "api/docuvieware3");
DocuViewareLicensing.RegisterKEY("XXXX"); // Unlocking DocuVieware

You need to replace "XXXX" by your actual license key.

.NET Core 2.0 DependencyContext, which is what Mvc uses to discover compile time references for views, doesn't have a resolver for referenced binaries. Consequently we need to modify the pieces in Mvc that use DependencyContext to locate reference assembly paths otherwise there will an error at runtime.

This is done by creating the ReferencesMetadataReferenceFeatureProvider class below. This shouldn't be necessary in the future starting with .NET Core 2.0.1 where this should be fixed, more information here: https://github.com/aspnet/Home/issues/2126#issuecomment-322325498

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.DependencyModel;

namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
{
   public class ReferencesMetadataReferenceFeatureProvider : IApplicationFeatureProvider
   {
      public void PopulateFeature(IEnumerable parts, MetadataReferenceFeature feature)
      {
         var libraryPaths = new HashSet(StringComparer.OrdinalIgnoreCase);
         foreach (var assemblyPart in parts.OfType())
         {
            var dependencyContext = DependencyContext.Load(assemblyPart.Assembly);
            if (dependencyContext != null)
            {
               foreach (var library in dependencyContext.CompileLibraries)
               {
                  if (string.Equals("reference", library.Type, StringComparison.OrdinalIgnoreCase))
                  {
                     foreach (var libraryAssembly in library.Assemblies)
                     {
                        libraryPaths.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, libraryAssembly));
                     }
                  }
                  else
                  {
                     foreach (var path in library.ResolveReferencePaths())
                     {
                        libraryPaths.Add(path);
                     }
                  }
               }
            }
            else
            {
               libraryPaths.Add(assemblyPart.Assembly.Location);
            }
         }
         foreach (var path in libraryPaths)
         {
            feature.MetadataReferences.Add(CreateMetadataReference(path));
         }
      }

      private static MetadataReference CreateMetadataReference(string path)
      {
         using (var stream = File.OpenRead(path))
         {
            var moduleMetadata = ModuleMetadata.CreateFromStream(stream, PEStreamOptions.PrefetchMetadata);
            var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata);

            return assemblyMetadata.GetReference(filePath: path);
         }
      }
   }
}

Finally you need to add this code to the ConfigureServices method in order to get the DocuVieware™ reference to work in the Razor views it will be integrated in.

services.AddMvc()
   // Enabling Web API 2 projects compatibility layout support for .NET Core
   .AddWebApiConventions()
   // .NET Core 2.0 DependencyContext doesn't have a resolver for referenced binaries.
   // More information: https://github.com/aspnet/Home/issues/2126#issuecomment-322325498
   .ConfigureApplicationPartManager(manager =>
   {
      var oldMetadataReferenceFeatureProvider = manager.FeatureProviders.First(f => f is MetadataReferenceFeatureProvider);
      manager.FeatureProviders.Remove(oldMetadataReferenceFeatureProvider);
      manager.FeatureProviders.Add(new ReferencesMetadataReferenceFeatureProvider());
   })
   // We need to explicitly add DocuVieware reference to Razor compilation using RazorViewEngineOptions.CompilationCallback
   .AddRazorOptions(options =>
   {
      var previous = options.CompilationCallback;
      options.CompilationCallback = context =>
      {
         previous?.Invoke(context);
         context.Compilation = context.Compilation.AddReferences(Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(DocuVieware).Assembly.Location));
      };
   });

Here is what the Startup.cs file should look like at this point:

 DocuVieware integration

First, you need an additional controller to handle and route the DocuVieware™ actions. Simply create a new controller called DocuVieware3Controller.cs in the project's Controllers folder as follow:

using Microsoft.AspNetCore.Mvc;
using GdPicture14.WEB;
using System.Net.Http;

namespace DocuViewareNetCore.Controllers
{
   [Route("api/docuvieware3")]
   public class DocuVieware3Controller : Controller
   {
      [HttpPost("init")]
      public string Init([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.init(jsonString);
      }

      [HttpPost("close")]
      public string Close([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.close(jsonString);
      }

      [HttpPost("selectpage")]
      public string SelectPage([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.selectpage(jsonString);
      }

      [HttpPost("rotate")]
      public string Rotate([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.rotate(jsonString);
      }

      [HttpPost("bookmarks")]
      public string Bookmarks([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.bookmarks(jsonString);
      }

      [HttpPost("thumbnails")]
      public string Thumbnails([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.thumbnails(jsonString);
      }

      [HttpPost("pageview")]
      public string PageView([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.pageview(jsonString);
      }

      [HttpPost("rundestination")]
      public string RunDestination([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.rundestination(jsonString);
      }

      [HttpPost("textsearch")]
      public string TextSearch([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.textsearch(jsonString);
      }

      [HttpPost("zoommode")]
      public string ZoomMode([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.zoommode(jsonString);
      }

      [HttpPost("zoomset")]
      public string ZoomSet([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.zoomset(jsonString);
      }

      [HttpPost("singlepageviewmode")]
      public string SinglePageViewMode([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.singlepageviewmode(jsonString);
      }

      [HttpPost("zoomin")]
      public string ZoomIn([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.zoomin(jsonString);
      }

      [HttpPost("zoomout")]
      public string ZoomOut([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.zoomout(jsonString);
      }

      [HttpPost("zoomrect")]
      public string ZoomRect([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.zoomrect(jsonString);
      }

      [HttpPost("newannotation")]
      public string NewAnnotation([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.newannotation(jsonString);
      }

      [HttpPost("newannotationcomment")]
      public string NewAnnotationComment([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.newannotationcomment(jsonString);
      }

      [HttpPost("print")]
      public string Print([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.print(jsonString);
      }

      [HttpPost("customaction")]
      public string CustomAction([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.customaction(jsonString);
      }

      [HttpGet("print")]
      public HttpResponseMessage Print(string sessionID, string pageRange, bool printAnnotations)
      {
         return DocuViewareControllerActionsHandler.print(sessionID, pageRange, printAnnotations);
      }

      [HttpGet("save")]
      public HttpResponseMessage Save(string sessionID, string fileName, string format, string pageRange)
      {
         return DocuViewareControllerActionsHandler.save(sessionID, fileName, format, pageRange);
      }

      [HttpGet("twainservicesetupdownload")]
      public HttpResponseMessage TwainServiceSetupDownload(string sessionID)
      {
         return DocuViewareControllerActionsHandler.twainservicesetupdownload(sessionID);
      }

      [HttpPost("formfieldupdate")]
      public string FormfieldUpdate([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.formfieldupdate(jsonString);
      }

      [HttpPost("annotupdate")]
      public string AnnotUpdate([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.annotupdate(jsonString);
      }

      [HttpPost("loadfromuri")]
      public string LoadFromUri([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.loadfromuri(jsonString);
      }

      [HttpPost("loadfromfile")]
      public string LoadFromFile([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.loadfromfile(jsonString);
      }

      [HttpPost("movepage")]
      public string MovePage([FromBody]object jsonString)
      {
         return DocuViewareControllerActionsHandler.movepage(jsonString);
      }
   }
}

You are going to integrate a DocuVieware™ instance in the Index view, but of course the exact same applies to any other view or content.

For the sake of clarity, replace the entire content of the Index view, remove other views and the shared layouts as well, you won't use them in this tutorial.

Create a div in Index.cshtml and insert the DocuVieware™ control in it. Then create a new DocuVieware™ object in the div and set its properties.

Here is what the Index.cshtml finally looks like after the integration is complete:

@using GdPicture14.WEB
@using System.Web.UI.WebControls

<!DOCTYPE html>

<html style="height: 100%">
<head>
   <meta name="viewport" content="width=device-width" />
   <title>DocuVieware ASP.NET Core demo application</title>
   <script src="~/Scripts/docuvieware-min.js"></script>
   <link href="~/css/docuvieware-min.css" rel="stylesheet" type="text/css" />
</head>
<body style="overflow: hidden; margin: 0; height: 100%;">
   <div style="width: 100%; height: 100%;">
      @{
         DocuVieware docuVieware = new DocuVieware
         {
            ID = "DocuVieware1",
            Height = new Unit("100%"),
            Width = new Unit("100%"),
            DisableAnnotationDrawingModePanel = true,
            EnableMultipleThumbnailSelection = false,
            EnableFormFieldsEdition = true
         };
         docuVieware.RenderControl(Output);
      }
   </div>
</body>
</html>

That’s it! You can start the project and load documents in your brand new DocuVieware™.