forked from docusign/code-examples-csharp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEg001EmbeddedSigningController.cs
215 lines (182 loc) · 8.79 KB
/
Eg001EmbeddedSigningController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
using System;
using System.Collections.Generic;
using DocuSign.eSign.Api;
using DocuSign.eSign.Client;
using DocuSign.eSign.Model;
using eg_03_csharp_auth_code_grant_core.Controllers;
using eg_03_csharp_auth_code_grant_core.Models;
using Microsoft.AspNetCore.Mvc;
namespace eg_03_csharp_auth_code_grant_core.Views
{
[Route("eg001")]
public class Eg001EmbeddedSigningController : EgController
{
private string dsPingUrl;
private string signerClientId = "1000";
private string dsReturnUrl;
public Eg001EmbeddedSigningController(DSConfiguration config, IRequestItemsService requestItemsService)
: base(config, requestItemsService)
{
dsPingUrl = config.AppUrl + "/";
dsReturnUrl = config.AppUrl + "/dsReturn";
ViewBag.title = "Embedded Signing Ceremony";
}
// ***DS.snippet.0.start
private string DoWork(string signerEmail, string signerName,
string accessToken, string basePath, string accountId)
{
// Data for this method
// signerEmail
// signerName
// accessToken
// basePath
// accountId
// dsPingUrl -- class global
// signerClientId -- class global
// dsReturnUrl -- class global
// Step 1. Create the envelope definition
EnvelopeDefinition envelope = MakeEnvelope(signerEmail, signerName);
// Step 2. Call DocuSign to create the envelope
var config = new Configuration(new ApiClient(basePath));
config.AddDefaultHeader("Authorization", "Bearer " + accessToken);
EnvelopesApi envelopesApi = new EnvelopesApi(config);
EnvelopeSummary results = envelopesApi.CreateEnvelope(accountId, envelope);
string envelopeId = results.EnvelopeId;
// Save for future use within the example launcher
RequestItemsService.EnvelopeId = envelopeId;
// Step 3. create the recipient view, the Signing Ceremony
RecipientViewRequest viewRequest = MakeRecipientViewRequest(signerEmail, signerName);
// call the CreateRecipientView API
ViewUrl results1 = envelopesApi.CreateRecipientView(accountId, envelopeId, viewRequest);
// Step 4. Redirect the user to the Signing Ceremony
// Don't use an iFrame!
// State can be stored/recovered using the framework's session or a
// query parameter on the returnUrl (see the makeRecipientViewRequest method)
string redirectUrl = results1.Url;
return redirectUrl;
}
private RecipientViewRequest MakeRecipientViewRequest(string signerEmail, string signerName)
{
// Data for this method
// signerEmail
// signerName
// dsPingUrl -- class global
// signerClientId -- class global
// dsReturnUrl -- class global
RecipientViewRequest viewRequest = new RecipientViewRequest();
// Set the url where you want the recipient to go once they are done signing
// should typically be a callback route somewhere in your app.
// The query parameter is included as an example of how
// to save/recover state information during the redirect to
// the DocuSign signing ceremony. It's usually better to use
// the session mechanism of your web framework. Query parameters
// can be changed/spoofed very easily.
viewRequest.ReturnUrl = dsReturnUrl + "?state=123";
// How has your app authenticated the user? In addition to your app's
// authentication, you can include authenticate steps from DocuSign.
// Eg, SMS authentication
viewRequest.AuthenticationMethod = "none";
// Recipient information must match embedded recipient info
// we used to create the envelope.
viewRequest.Email = signerEmail;
viewRequest.UserName = signerName;
viewRequest.ClientUserId = signerClientId;
// DocuSign recommends that you redirect to DocuSign for the
// Signing Ceremony. There are multiple ways to save state.
// To maintain your application's session, use the pingUrl
// parameter. It causes the DocuSign Signing Ceremony web page
// (not the DocuSign server) to send pings via AJAX to your
// app,
viewRequest.PingFrequency = "600"; // seconds
// NOTE: The pings will only be sent if the pingUrl is an https address
viewRequest.PingUrl = dsPingUrl; // optional setting
return viewRequest;
}
private EnvelopeDefinition MakeEnvelope(string signerEmail, string signerName)
{
// Data for this method
// signerEmail
// signerName
// signerClientId -- class global
// Config.docPdf
byte[] buffer = System.IO.File.ReadAllBytes(Config.docPdf);
EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition();
envelopeDefinition.EmailSubject = "Please sign this document";
Document doc1 = new Document();
String doc1b64 = Convert.ToBase64String(buffer);
doc1.DocumentBase64 = doc1b64;
doc1.Name = "Lorem Ipsum"; // can be different from actual file name
doc1.FileExtension = "pdf";
doc1.DocumentId = "3";
// The order in the docs array determines the order in the envelope
envelopeDefinition.Documents = new List<Document> { doc1 };
// Create a signer recipient to sign the document, identified by name and email
// We set the clientUserId to enable embedded signing for the recipient
// We're setting the parameters via the object creation
Signer signer1 = new Signer {
Email = signerEmail,
Name = signerName,
ClientUserId = signerClientId,
RecipientId = "1"
};
// Create signHere fields (also known as tabs) on the documents,
// We're using anchor (autoPlace) positioning
//
// The DocuSign platform seaches throughout your envelope's
// documents for matching anchor strings.
SignHere signHere1 = new SignHere
{
AnchorString = "/sn1/",
AnchorUnits = "pixels",
AnchorXOffset = "10",
AnchorYOffset = "20"
};
// Tabs are set per recipient / signer
Tabs signer1Tabs = new Tabs
{
SignHereTabs = new List<SignHere> { signHere1 }
};
signer1.Tabs = signer1Tabs;
// Add the recipient to the envelope object
Recipients recipients = new Recipients
{
Signers = new List<Signer> { signer1 }
};
envelopeDefinition.Recipients = recipients;
// Request that the envelope be sent by setting |status| to "sent".
// To request that the envelope be created as a draft, set to "created"
envelopeDefinition.Status = "sent";
return envelopeDefinition;
}
// ***DS.snippet.0.end
public override string EgName => "eg001";
[HttpPost]
public IActionResult Create(string signerEmail, string signerName)
{
// Data for this method
// signerEmail
// signerName
// dsPingUrl -- class global
// signerClientId -- class global
// dsReturnUrl -- class global
string accessToken = RequestItemsService.User.AccessToken;
string basePath = RequestItemsService.Session.BasePath + "/restapi";
string accountId = RequestItemsService.Session.AccountId;
// Check the token with minimal buffer time.
bool tokenOk = CheckToken(3);
if (!tokenOk)
{
// We could store the parameters of the requested operation
// so it could be restarted automatically.
// But since it should be rare to have a token issue here,
// we'll make the user re-enter the form data after
// authentication.
RequestItemsService.EgName = EgName;
return Redirect("/ds/mustAuthenticate");
}
string redirectUrl = DoWork(signerEmail, signerName, accessToken, basePath, accountId);
// Redirect the user to the Signing Ceremony
return Redirect(redirectUrl);
}
}
}