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.
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.
- 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.
- public string ValidateDoc {
- get;
- set;
- }
Now, assign the authorityURL path to ValidateDoc property while looping the Recipient envelops.
- recipientsDocs.Add(new DocusignDemo.Models.Recipient {
- EnvelopeID = recipient.EnvelopeID, Name = recipient.Name, Email = recipient.Email, Status = signingStatus, documentURL = SignedPDF, SentOn = recipient.SentOn, UpdatedOn = recipient.UpdatedOn, ValidateDoc = authorityURL
- });
View
Add two more columns in an existing view table and make it hidden.
- <td hidden="hidden" class="docURL"> @Html.DisplayFor(modelItem => item.ValidateDoc)</td>
- <td>
- <button class="viewDoc">View</button>
- </td>
Now, run your application, In the below image you can see that we have added one visible column "Validate".
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
- <div class="modal" id="myModal">
- <div class="modal-dialog" style="width:50%">
- <div class="modal-content">
- <!-- Modal Header -->
- <div class="modal-header">
- <h4 class="modal-title">Validate Document</h4>
- <button type="button" class="close" data-dismiss="modal">×</button>
- </div>
- <!-- Modal body -->
- <div class="modal-body" id="test1">
- <div id="iframeHolder"></div>
- </div>
- <!-- Modal footer -->
- <div class="modal-footer">
- <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
- </div>
- </div>
- </div>
- </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).
- <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.
- <script type="text/javascript">
- $(document).ready(function() {
- $("#myTable td").click(function(e) {
- var docURL = $(this).closest('tr').children('td.docURL').text();
- $('#myModal').modal();
- $('#iframeHolder').html('<iframe id="iframe" src=' + docURL + ' width="100%" height="450"></iframe>');
- });
- });
- </script>
Now, run your application.
Similarly, we can view the Summary Document.
In the coming article, we will see how to merge these into one document.
Complete View
- @model IEnumerable<DocusignDemo.Models.Recipient>
- @{
-
- ViewBag.Title = "ListDocuments";
- Layout = "~/Views/Shared/_Layout.cshtml";
- }
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- </head>
- <script src="~/Scripts/jquery-1.10.2.min.js"></script>
- <script src="~/Scripts/bootstrap.min.js"></script>
- <script type="text/javascript">
- $(document).ready(function() {
- $("#myTable td").click(function(e) {
- var docURL = $(this).closest('tr').children('td.docURL').text();
- $('#myModal').modal();
- $('#iframeHolder').html('<iframe id="iframe" src=' + docURL + ' width="100%" height="450"></iframe>');
- });
- });
- </script>
-
- <body style="margin-top:20px">
- <div class="container">
- <div class="table-responsive">
- <table id="myTable" class="table table-bordered">
- <thead class="btn-primary">
- <tr>
- <th> @Html.DisplayNameFor(model => model.Name) </th>
- <th> @Html.DisplayNameFor(model => model.Email) </th>
- <th> @Html.DisplayNameFor(model => model.EnvelopeID) </th> @*<th> @Html.DisplayNameFor(model => model.Status) </th>*@ <th> @Html.DisplayNameFor(model => model.SentOn) </th>
- <th> @Html.DisplayNameFor(model => model.UpdatedOn) </th>
- <th> Download </th>
- <th> Validate </th>
- </tr>
- </thead>
- <tbody> @foreach (var item in Model) { <tr>
- <td> @Html.DisplayFor(modelItem => item.Name) </td>
- <td> @Html.DisplayFor(modelItem => item.Email) </td>
- <td> @Html.DisplayFor(modelItem => item.EnvelopeID) </td> @*<td> @Html.DisplayFor(modelItem => item.Status) </td>*@ <td> @Html.DisplayFor(modelItem => item.SentOn) </td>
- <td> @Html.DisplayFor(modelItem => item.UpdatedOn) </td>
- <td> @*@Html.DisplayFor(modelItem => item.documentURL)*@ @Html.ActionLink(item.Status, "Download", "Docusign", new { filePath = item.documentURL }, null) </td>
- <td hidden="hidden" class="docURL"> @Html.DisplayFor(modelItem => item.ValidateDoc)</td>
- <td>
- <button class="viewDoc">View</button>
- </td>
- </tr> } </tbody>
- </table>
- </div>
- </div>
- </body>
- <!-- The Modal -->
- <div class="modal" id="myModal">
- <div class="modal-dialog" style="width:50%">
- <div class="modal-content">
- <!-- Modal Header -->
- <div class="modal-header">
- <h4 class="modal-title">Validate Document</h4>
- <button type="button" class="close" data-dismiss="modal">×</button>
- </div>
- <!-- Modal body -->
- <div class="modal-body" id="test1">
- <div id="iframeHolder"></div>
- </div>
- <!-- Modal footer -->
- <div class="modal-footer">
- <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
- </div>
- </div>
- </div>
- </div>
Complete Controller
- List < DocusignDemo.Models.Recipient > recipientsDocs = new List < DocusignDemo.Models.Recipient > ();
- public ActionResult ListDocuments() {
- ApiClient apiClient = new ApiClient("https://demo.docusign.net/restapi");
- Configuration.Default.ApiClient = apiClient;
- MyCredential myCredential = new MyCredential();
-
- string accountId = loginApi(myCredential.UserName, myCredential.Password);
- DocusignDemo.Models.CSharpCornerEntities cSharpCornerEntities = new DocusignDemo.Models.CSharpCornerEntities();
- var recipients = cSharpCornerEntities.Recipients.ToList();
- string serverDirectory = Server.MapPath("~/Uploadfiles/");
- if (!Directory.Exists(serverDirectory)) {
- Directory.CreateDirectory(serverDirectory);
- }
- foreach(var recipient in recipients) {
- string recipientDirectory = Server.MapPath("~/Uploadfiles/" + recipient.EnvelopeID);
- if (!Directory.Exists(recipientDirectory)) {
- Directory.CreateDirectory(recipientDirectory);
- }
- EnvelopeDocumentsResult documentList = ListEnvelopeDocuments(accountId, recipient.EnvelopeID);
- int i = 0;
- string SignedPDF = string.Empty;
- EnvelopesApi envelopesApi = new EnvelopesApi();
- foreach(var document in documentList.EnvelopeDocuments) {
- string signingStatus = recipient.Status == "completed" ? "Signed" : "Yet to Sign";
- MemoryStream docStream = (MemoryStream) envelopesApi.GetDocument(accountId, recipient.EnvelopeID, documentList.EnvelopeDocuments[i].DocumentId);
- string documentName = document.Name != "Summary" ? document.Name : "Summary";
- SignedPDF = Server.MapPath("~/Uploadfiles/" + recipient.EnvelopeID + "/" + recipient.EnvelopeID + "_" + documentName + ".pdf");
- using(var fileStream = System.IO.File.Create(SignedPDF)) {
- docStream.Seek(0, SeekOrigin.Begin);
- docStream.CopyTo(fileStream);
- }
- var authorityURL = "http://" + HttpContext.Request.Url.Authority + "/Uploadfiles/" + recipient.EnvelopeID + "/" + recipient.EnvelopeID + "_" + documentName + ".pdf";
- recipientsDocs.Add(new DocusignDemo.Models.Recipient {
- EnvelopeID = recipient.EnvelopeID, Name = recipient.Name, Email = recipient.Email, Status = signingStatus, documentURL = SignedPDF, SentOn = recipient.SentOn, UpdatedOn = recipient.UpdatedOn, ValidateDoc = authorityURL
- });
- i++;
- }
- }
- return View(recipientsDocs);
- }
- public EnvelopeDocumentsResult ListEnvelopeDocuments(string accountId, string envelopeId) {
- EnvelopesApi envelopesApi = new EnvelopesApi();
- EnvelopeDocumentsResult docsList = envelopesApi.ListDocuments(accountId, envelopeId);
- return docsList;
- }
- public FileResult Download(string filePath) {
- string fileName = Path.GetFileName(filePath);
- string contentType = "application/pdf";
- return File(filePath, contentType, fileName);
- }
Model
- List < DocusignDemo.Models.Recipient > recipientsDocs = new List < DocusignDemo.Models.Recipient > ();
- public ActionResult ListDocuments() {
- ApiClient apiClient = new ApiClient("https://demo.docusign.net/restapi");
- Configuration.Default.ApiClient = apiClient;
- MyCredential myCredential = new MyCredential();
-
- string accountId = loginApi(myCredential.UserName, myCredential.Password);
- DocusignDemo.Models.CSharpCornerEntities cSharpCornerEntities = new DocusignDemo.Models.CSharpCornerEntities();
- var recipients = cSharpCornerEntities.Recipients.ToList();
- string serverDirectory = Server.MapPath("~/Uploadfiles/");
- if (!Directory.Exists(serverDirectory)) {
- Directory.CreateDirectory(serverDirectory);
- }
- foreach(var recipient in recipients) {
- string recipientDirectory = Server.MapPath("~/Uploadfiles/" + recipient.EnvelopeID);
- if (!Directory.Exists(recipientDirectory)) {
- Directory.CreateDirectory(recipientDirectory);
- }
- EnvelopeDocumentsResult documentList = ListEnvelopeDocuments(accountId, recipient.EnvelopeID);
- int i = 0;
- string SignedPDF = string.Empty;
- EnvelopesApi envelopesApi = new EnvelopesApi();
- foreach(var document in documentList.EnvelopeDocuments) {
- string signingStatus = recipient.Status == "completed" ? "Signed" : "Yet to Sign";
- MemoryStream docStream = (MemoryStream) envelopesApi.GetDocument(accountId, recipient.EnvelopeID, documentList.EnvelopeDocuments[i].DocumentId);
- string documentName = document.Name != "Summary" ? document.Name : "Summary";
- SignedPDF = Server.MapPath("~/Uploadfiles/" + recipient.EnvelopeID + "/" + recipient.EnvelopeID + "_" + documentName + ".pdf");
- using(var fileStream = System.IO.File.Create(SignedPDF)) {
- docStream.Seek(0, SeekOrigin.Begin);
- docStream.CopyTo(fileStream);
- }
- var authorityURL = "http://" + HttpContext.Request.Url.Authority + "/Uploadfiles/" + recipient.EnvelopeID + "/" + recipient.EnvelopeID + "_" + documentName + ".pdf";
- recipientsDocs.Add(new DocusignDemo.Models.Recipient {
- EnvelopeID = recipient.EnvelopeID, Name = recipient.Name, Email = recipient.Email, Status = signingStatus, documentURL = SignedPDF, SentOn = recipient.SentOn, UpdatedOn = recipient.UpdatedOn, ValidateDoc = authorityURL
- });
- i++;
- }
- }
- return View(recipientsDocs);
- }
- public EnvelopeDocumentsResult ListEnvelopeDocuments(string accountId, string envelopeId) {
- EnvelopesApi envelopesApi = new EnvelopesApi();
- EnvelopeDocumentsResult docsList = envelopesApi.ListDocuments(accountId, envelopeId);
- return docsList;
- }
- public FileResult Download(string filePath) {
- string fileName = Path.GetFileName(filePath);
- string contentType = "application/pdf";
- return File(filePath, contentType, fileName);
- }
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.