ASP.NET MVC 5 - DocuSign🖋️- Validating And Viewing Document(s) On A Modal-Dialog

In this article, we will see how to validate the DocuSign document by viewing it in Modal Dialog using an iframe in our web application.

Introduction 
 
In this article, we will see how to validate the DocuSign document by viewing it in Modal Dialog using an iframe in our web application. Please take a look at my previous articles for basic account creation, integration, validation, and creation of a signature request on a document, storing the envelope information, signing on a document and tracking envelopes, getting the document(s) from DocuSign using envelope id, storing it to a local directory, and listing and downloading in the web application view.
Let's move forward as an admin to Validate or View the DocuSign document(s) in our application.
 
Prerequisites
  • Visual Studio
  • Basic knowledge of ASP.NET MVC
  • Basic knowledge of C#
  • Should have an account on DocuSign
  • Basic Knowledge of DocuSign
Get the URL of The Current Page -- Why?
 
In the last article, we have seen how to Get, Store, and Download the document(s) from DocuSign, right? There, we have passed the local path of the document. So, we can't view the document(s) using local path in an iframe because it will fall into File URL “Not allowed to load local resource” in the Browser exception. It is a security exception built into Chrome and other modern browsers. The wording may be different but in some way, shape, or form, they all have security exceptions in place to deal with this scenario.
 
ASP.NET MVC 5 - DocuSign- Validating and Viewing The Document(s) on a Modal-dialog Using IFrame in Our Web Application 
 
In this scenario, we have to go with the current page URL or domain. So here, we are going to fetch the URL of the current page using HttpContext.Current.Request. When working on an app, you might also want to get different results for different purposes. Let’s go through them, one by one.
 
My Local Current Page URL is -
 
http://localhost:57805/Docusign/ListDocuments
  • HttpContext.Current.Request.Url.AbsoluteUri 
    This will return localhost URL if you are in the local environment for example, or it will return the absolute URL. www.c-sharpcorner.com, for our C# corner site. It should be kept in mind that Url.AbsoluteUri does return anything after the “#” symbol.
     
  • HttpContext.Current.Request.Url.AbsolutePath 
    This will return  /Docusign/ListDocuments
     
  • HttpContext.Current.Request.Url.Host
    This will return "localhost" 

  • HttpContext.Current.Request.Url.Authority
    This will return “llocalhost:57805”.
     
  • HttpContext.Current.Request.Url.Port 
    This will return  "57805"
Controller
 
Here, Url.Authority is the best choice for our needs. In the last article, we stored all the DocuSign documents under the uploadfiles folder. Now, let us make the valid URL to view in IFrame.
  1. var authorityURL = "http://" + HttpContext.Request.Url.Authority + "/Uploadfiles/" + recipient.EnvelopeID + "/" + recipient.EnvelopeID + "_" + documentName + ".pdf";  
And created one property to hold this AuthorityUrl in the Recipient model.
  1. public string ValidateDoc {  
  2.     get;  
  3.     set;  
  4. }  
Now, assign the authorityURL path to ValidateDoc property while looping the Recipient envelops.
  1. recipientsDocs.Add(new DocusignDemo.Models.Recipient {  
  2.     EnvelopeID = recipient.EnvelopeID, Name = recipient.Name, Email = recipient.Email, Status = signingStatus, documentURL = SignedPDF, SentOn = recipient.SentOn, UpdatedOn = recipient.UpdatedOn, ValidateDoc = authorityURL  
  3. });  
View 
 
Add two more columns in an existing view table and make it hidden.
  1. <td hidden="hidden" class="docURL"> @Html.DisplayFor(modelItem => item.ValidateDoc)</td>  
  2. <td>  
  3. <button class="viewDoc">View</button>  
  4. </td>  
Now, run your application, In the below image you can see that we have added one visible column "Validate".
 
ASP.NET MVC 5 - DocuSign- Validating and Viewing The Document(s) on a Modal-dialog Using IFrame in Our Web Application 
Show Modal Dialog with Respective Document 
 
Now we have to show the modal dialog on click of view button with the respective document for the respective recipient. Let's create a bootstrap modal dialog
  1. <div class="modal" id="myModal">  
  2.     <div class="modal-dialog" style="width:50%">  
  3.         <div class="modal-content">  
  4.             <!-- Modal Header -->  
  5.             <div class="modal-header">  
  6.                 <h4 class="modal-title">Validate Document</h4>  
  7.                 <button type="button" class="close" data-dismiss="modal">×</button>  
  8.             </div>  
  9.             <!-- Modal body -->  
  10.             <div class="modal-body" id="test1">  
  11.                 <div id="iframeHolder"></div>  
  12.             </div>  
  13.             <!-- Modal footer -->  
  14.             <div class="modal-footer">  
  15.                 <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>  
  16.             </div>  
  17.         </div>  
  18.     </div>  
  19. </div>  
In the above modal dialog code, I have manually added one div under Modal-body which will act as IFrame to show the document(s).
  1. <div id="iframeHolder"></div>   
Create IFrame and Show Modal-Dialog while clicking on the view button 
 
Our table id is  "myTable" and we are getting the "docURL" while clicking on the td in a respective row.
  1. <script type="text/javascript">  
  2.     $(document).ready(function() {  
  3.         $("#myTable td").click(function(e) {  
  4.             var docURL = $(this).closest('tr').children('td.docURL').text();  
  5.             $('#myModal').modal();  
  6.             $('#iframeHolder').html('<iframe id="iframe" src=' + docURL + ' width="100%" height="450"></iframe>');  
  7.         });  
  8.     });  
  9. </script>  
Now, run your application. 
 
 ASP.NET MVC 5 - DocuSign- Validating and Viewing The Document(s) on a Modal-dialog Using IFrame in Our Web Application
 
Similarly, we can view the Summary Document.
 
 ASP.NET MVC 5 - DocuSign- Validating and Viewing The Document(s) on a Modal-dialog Using IFrame in Our Web Application
 
In the coming article, we will see how to merge these into one document.
 
Complete View
  1. @model IEnumerable<DocusignDemo.Models.Recipient>  
  2. @{  
  3.    /**/  
  4.    ViewBag.Title = "ListDocuments";  
  5.    Layout = "~/Views/Shared/_Layout.cshtml";  
  6. }  
  7. <head>  
  8.     <meta charset="utf-8">  
  9.     <meta name="viewport" content="width=device-width, initial-scale=1">  
  10. </head>  
  11. <script src="~/Scripts/jquery-1.10.2.min.js"></script>  
  12. <script src="~/Scripts/bootstrap.min.js"></script>  
  13. <script type="text/javascript">  
  14.     $(document).ready(function() {  
  15.         $("#myTable td").click(function(e) {  
  16.             var docURL = $(this).closest('tr').children('td.docURL').text();  
  17.             $('#myModal').modal();  
  18.             $('#iframeHolder').html('<iframe id="iframe" src=' + docURL + ' width="100%" height="450"></iframe>');  
  19.         });  
  20.     });  
  21. </script>  
  22.   
  23. <body style="margin-top:20px">  
  24.     <div class="container">  
  25.         <div class="table-responsive">  
  26.             <table id="myTable" class="table table-bordered">  
  27.                 <thead class="btn-primary">  
  28.                     <tr>  
  29.                         <th> @Html.DisplayNameFor(model => model.Name) </th>  
  30.                         <th> @Html.DisplayNameFor(model => model.Email) </th>  
  31.                         <th> @Html.DisplayNameFor(model => model.EnvelopeID) </th> @*<th> @Html.DisplayNameFor(model => model.Status) </th>*@ <th> @Html.DisplayNameFor(model => model.SentOn) </th>  
  32.                         <th> @Html.DisplayNameFor(model => model.UpdatedOn) </th>  
  33.                         <th> Download </th>  
  34.                         <th> Validate </th>  
  35.                     </tr>  
  36.                 </thead>  
  37.                 <tbody> @foreach (var item in Model) { <tr>  
  38.                         <td> @Html.DisplayFor(modelItem => item.Name) </td>  
  39.                         <td> @Html.DisplayFor(modelItem => item.Email) </td>  
  40.                         <td> @Html.DisplayFor(modelItem => item.EnvelopeID) </td> @*<td> @Html.DisplayFor(modelItem => item.Status) </td>*@ <td> @Html.DisplayFor(modelItem => item.SentOn) </td>  
  41.                         <td> @Html.DisplayFor(modelItem => item.UpdatedOn) </td>  
  42.                         <td> @*@Html.DisplayFor(modelItem => item.documentURL)*@ @Html.ActionLink(item.Status, "Download""Docusign"new { filePath = item.documentURL }, null) </td>  
  43.                         <td hidden="hidden" class="docURL"> @Html.DisplayFor(modelItem => item.ValidateDoc)</td>  
  44.                         <td>  
  45.                             <button class="viewDoc">View</button>  
  46.                         </td>  
  47.                     </tr> } </tbody>  
  48.             </table>  
  49.         </div>  
  50.     </div>  
  51. </body>  
  52. <!-- The Modal -->  
  53. <div class="modal" id="myModal">  
  54.     <div class="modal-dialog" style="width:50%">  
  55.         <div class="modal-content">  
  56.             <!-- Modal Header -->  
  57.             <div class="modal-header">  
  58.                 <h4 class="modal-title">Validate Document</h4>  
  59.                 <button type="button" class="close" data-dismiss="modal">×</button>  
  60.             </div>  
  61.             <!-- Modal body -->  
  62.             <div class="modal-body" id="test1">  
  63.                 <div id="iframeHolder"></div>  
  64.             </div>  
  65.             <!-- Modal footer -->  
  66.             <div class="modal-footer">  
  67.                 <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>  
  68.             </div>  
  69.         </div>  
  70.     </div>  
  71. </div>  
Complete Controller
  1. List < DocusignDemo.Models.Recipient > recipientsDocs = new List < DocusignDemo.Models.Recipient > ();  
  2. public ActionResult ListDocuments() {  
  3.     ApiClient apiClient = new ApiClient("https://demo.docusign.net/restapi");  
  4.     Configuration.Default.ApiClient = apiClient;  
  5.     MyCredential myCredential = new MyCredential();  
  6.     // call the Login() API which sets the user's baseUrl and returns their accountId  
  7.     string accountId = loginApi(myCredential.UserName, myCredential.Password);  
  8.     DocusignDemo.Models.CSharpCornerEntities cSharpCornerEntities = new DocusignDemo.Models.CSharpCornerEntities();  
  9.     var recipients = cSharpCornerEntities.Recipients.ToList();  
  10.     string serverDirectory = Server.MapPath("~/Uploadfiles/");  
  11.     if (!Directory.Exists(serverDirectory)) {  
  12.         Directory.CreateDirectory(serverDirectory);  
  13.     }  
  14.     foreach(var recipient in recipients) {  
  15.         string recipientDirectory = Server.MapPath("~/Uploadfiles/" + recipient.EnvelopeID);  
  16.         if (!Directory.Exists(recipientDirectory)) {  
  17.             Directory.CreateDirectory(recipientDirectory);  
  18.         }  
  19.         EnvelopeDocumentsResult documentList = ListEnvelopeDocuments(accountId, recipient.EnvelopeID);  
  20.         int i = 0;  
  21.         string SignedPDF = string.Empty;  
  22.         EnvelopesApi envelopesApi = new EnvelopesApi();  
  23.         foreach(var document in documentList.EnvelopeDocuments) {  
  24.             string signingStatus = recipient.Status == "completed" ? "Signed" : "Yet to Sign";  
  25.             MemoryStream docStream = (MemoryStream) envelopesApi.GetDocument(accountId, recipient.EnvelopeID, documentList.EnvelopeDocuments[i].DocumentId);  
  26.             string documentName = document.Name != "Summary" ? document.Name : "Summary";  
  27.             SignedPDF = Server.MapPath("~/Uploadfiles/" + recipient.EnvelopeID + "/" + recipient.EnvelopeID + "_" + documentName + ".pdf");  
  28.             using(var fileStream = System.IO.File.Create(SignedPDF)) {  
  29.                 docStream.Seek(0, SeekOrigin.Begin);  
  30.                 docStream.CopyTo(fileStream);  
  31.             }  
  32.             var authorityURL = "http://" + HttpContext.Request.Url.Authority + "/Uploadfiles/" + recipient.EnvelopeID + "/" + recipient.EnvelopeID + "_" + documentName + ".pdf";  
  33.             recipientsDocs.Add(new DocusignDemo.Models.Recipient {  
  34.                 EnvelopeID = recipient.EnvelopeID, Name = recipient.Name, Email = recipient.Email, Status = signingStatus, documentURL = SignedPDF, SentOn = recipient.SentOn, UpdatedOn = recipient.UpdatedOn, ValidateDoc = authorityURL  
  35.             });  
  36.             i++;  
  37.         }  
  38.     }  
  39.     return View(recipientsDocs);  
  40. }  
  41. public EnvelopeDocumentsResult ListEnvelopeDocuments(string accountId, string envelopeId) {  
  42.     EnvelopesApi envelopesApi = new EnvelopesApi();  
  43.     EnvelopeDocumentsResult docsList = envelopesApi.ListDocuments(accountId, envelopeId);  
  44.     return docsList;  
  45. }  
  46. public FileResult Download(string filePath) {  
  47.     string fileName = Path.GetFileName(filePath);  
  48.     string contentType = "application/pdf";  
  49.     return File(filePath, contentType, fileName);  
  50. }  
Model
  1. List < DocusignDemo.Models.Recipient > recipientsDocs = new List < DocusignDemo.Models.Recipient > ();  
  2. public ActionResult ListDocuments() {  
  3.     ApiClient apiClient = new ApiClient("https://demo.docusign.net/restapi");  
  4.     Configuration.Default.ApiClient = apiClient;  
  5.     MyCredential myCredential = new MyCredential();  
  6.     // call the Login() API which sets the user's baseUrl and returns their accountId  
  7.     string accountId = loginApi(myCredential.UserName, myCredential.Password);  
  8.     DocusignDemo.Models.CSharpCornerEntities cSharpCornerEntities = new DocusignDemo.Models.CSharpCornerEntities();  
  9.     var recipients = cSharpCornerEntities.Recipients.ToList();  
  10.     string serverDirectory = Server.MapPath("~/Uploadfiles/");  
  11.     if (!Directory.Exists(serverDirectory)) {  
  12.         Directory.CreateDirectory(serverDirectory);  
  13.     }  
  14.     foreach(var recipient in recipients) {  
  15.         string recipientDirectory = Server.MapPath("~/Uploadfiles/" + recipient.EnvelopeID);  
  16.         if (!Directory.Exists(recipientDirectory)) {  
  17.             Directory.CreateDirectory(recipientDirectory);  
  18.         }  
  19.         EnvelopeDocumentsResult documentList = ListEnvelopeDocuments(accountId, recipient.EnvelopeID);  
  20.         int i = 0;  
  21.         string SignedPDF = string.Empty;  
  22.         EnvelopesApi envelopesApi = new EnvelopesApi();  
  23.         foreach(var document in documentList.EnvelopeDocuments) {  
  24.             string signingStatus = recipient.Status == "completed" ? "Signed" : "Yet to Sign";  
  25.             MemoryStream docStream = (MemoryStream) envelopesApi.GetDocument(accountId, recipient.EnvelopeID, documentList.EnvelopeDocuments[i].DocumentId);  
  26.             string documentName = document.Name != "Summary" ? document.Name : "Summary";  
  27.             SignedPDF = Server.MapPath("~/Uploadfiles/" + recipient.EnvelopeID + "/" + recipient.EnvelopeID + "_" + documentName + ".pdf");  
  28.             using(var fileStream = System.IO.File.Create(SignedPDF)) {  
  29.                 docStream.Seek(0, SeekOrigin.Begin);  
  30.                 docStream.CopyTo(fileStream);  
  31.             }  
  32.             var authorityURL = "http://" + HttpContext.Request.Url.Authority + "/Uploadfiles/" + recipient.EnvelopeID + "/" + recipient.EnvelopeID + "_" + documentName + ".pdf";  
  33.             recipientsDocs.Add(new DocusignDemo.Models.Recipient {  
  34.                 EnvelopeID = recipient.EnvelopeID, Name = recipient.Name, Email = recipient.Email, Status = signingStatus, documentURL = SignedPDF, SentOn = recipient.SentOn, UpdatedOn = recipient.UpdatedOn, ValidateDoc = authorityURL  
  35.             });  
  36.             i++;  
  37.         }  
  38.     }  
  39.     return View(recipientsDocs);  
  40. }  
  41. public EnvelopeDocumentsResult ListEnvelopeDocuments(string accountId, string envelopeId) {  
  42.     EnvelopesApi envelopesApi = new EnvelopesApi();  
  43.     EnvelopeDocumentsResult docsList = envelopesApi.ListDocuments(accountId, envelopeId);  
  44.     return docsList;  
  45. }  
  46. public FileResult Download(string filePath) {  
  47.     string fileName = Path.GetFileName(filePath);  
  48.     string contentType = "application/pdf";  
  49.     return File(filePath, contentType, fileName);  
  50. }  
Summary
 
In this article, we discussed how to validate the DocuSign document(s) by viewing it in a Modal Dialog using Iframe in our web application. I hope it will help you. Your valuable feedback and comments about this article are always welcome.