Introduction
In this article, we will see how to get the document(s) from DocuSign using envelope id, store it to a local directory, and list and download in the web application view. 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, sign on a document and track envelopes within our application.
- ASP.NET MVC 5 - Integrate And Validate DocuSign Connection With Web Application
- ASP.NET MVC 5 - DocuSign - Send A Document For Signature From Web Application
- ASP.NET MVC 5 - DocuSign - Get And Store Envelop Information Into Database Using EF
- ASP.NET MVC 5 - DocuSign - Sign On A Document And Track Envelopes
Let's move forward to get and download the document(s) for respective envelopes.
Prerequisites
- Visual Studio
- Basic knowledge of ASP.NET MVC
- Basic knowledge of C#
- Should have an account on DocuSign
Article Flow
- Get document(s) using Envelop id and Store document(s) to Local Directory
- List document(s) in view
- Download document(s)
In the last article, we have seen how to view the document using mailbox or DocuSign portal. Now, let's try to get the document from DocuSign to our application. We can get the documents using a DocuSign account and recipient envelope id. In the below code, we are getting an account id by passing the DocuSign credentials.
- public string loginApi(string usr, string pwd) {
- // we set the api client in global config when we configured the client
- ApiClient apiClient = Configuration.Default.ApiClient;
- string authHeader = "{\"Username\":\"" + usr + "\", \"Password\":\"" + pwd + "\", \"IntegratorKey\":\"" + INTEGRATOR_KEY + "\"}";
- Configuration.Default.AddDefaultHeader("X-DocuSign-Authentication", authHeader);
- // we will retrieve this from the login() results
- string accountId = null;
- // the authentication api uses the apiClient (and X-DocuSign-Authentication header) that are set in Configuration object
- AuthenticationApi authApi = new AuthenticationApi();
- LoginInformation loginInfo = authApi.Login();
- // find the default account for this user
- foreach(DocuSign.eSign.Model.LoginAccount loginAcct in loginInfo.LoginAccounts) {
- if (loginAcct.IsDefault == "true") {
- accountId = loginAcct.AccountId;
- break;
- }
- }
- if (accountId == null) { // if no default found set to first account
- accountId = loginInfo.LoginAccounts[0].AccountId;
- }
- return accountId;
- }
And, we have stored the recipient's envelope information in our local database. So, we can get the envelope information by calling the recipient table. Now, let's loop the table values.
- 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();
- // call the Login() API which sets the user's baseUrl and returns their accountId
- 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) {
- if (recipient.Name == "GnanavelSekar") {
- 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);
- }
- 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
- });
- i++;
- }
- }
- }
- return View(recipientsDocs);
- }
In the above code, we are getting the list of recipients. For that, I have created the list object to hold it. Then, we have created the local directory to store the recipient documents. Now, let's loop the recipient to get the list of documents. And we have created a directory for each recipient envelope.
- public EnvelopeDocumentsResult ListEnvelopeDocuments(string accountId, string envelopeId) {
- EnvelopesApi envelopesApi = new EnvelopesApi();
- EnvelopeDocumentsResult docsList = envelopesApi.ListDocuments(accountId, envelopeId);
- return docsList;
- }
Every time, we will get the two documents for each envelop.
- Sent document with/without Signature
- Certified document - It represents the Summary document; it contains the information, such as sender details, recipient details, etc.
List document(s) in View
We have got the list of the documents in "recipientsDocs" object. Now, let's create a strongly typed view to list these documents.
- @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">
- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
- </head>
- <body style="margin-top:20px">
- <div class="container">
- <div class="table-responsive">
- <table 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> @Html.DisplayNameFor(model => model.documentURL) </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) </td>
- </tr>
- }
- </tbody>
- </table>
- </div>
- </div>
- </body>
Now, run your application.


ahtasham ulhaqPosted Mar 11, 2022, 7:35 AM
CSharpCornerEntities is missing can you please guide in this regard's
Developer SekarPosted Jun 4, 2019, 2:42 AM
Hi, how to get document fields and set required dynamically without creating a custom tab or custom fields.
Santhosh KadambariPosted Apr 12, 2019, 12:16 PM
Hello..why can't we use our own document server for storing the signed documents? Why should we use docusign or any other service? Can't we create our own apps for signing and storing the signed documents. We are a small organization and we just want to save money to add code to our apps to enable the users to sign and so we can save the signed documents to our servers.