![](/img/trans.png)
[英]DocuSign API: Signing issues with sending multiple documents in the same envelope
[英]Trying to create DocuSign envelope with multiple documents
我正在嘗試使用DocuSign REST API創建包含多個文檔的信封,我創建了一個C#控制台應用程序,並以JSON格式在請求中編寫了包絡參數。 我收到錯誤代碼“ENVELOPE IS INCOMPLETE”,我一直試圖將我的請求與REST API Docusign指南中的請求進行比較,我看不到我缺少的內容。 這是我的示例代碼:
[EDITED]
public class RequestSignature
{
// Enter your info here:
static string email = "email";
static string password = "password";
static string integratorKey = "key";
public static void Main()
{
string url = "https://demo.docusign.net/restapi/v2/login_information";
string baseURL = ""; // we will retrieve this
string accountId = ""; // will retrieve
var objectCredentials = new { Username = email, Password = password, IntegratorKey = integratorKey };
string jSONCredentialsString = JsonConvert.SerializeObject(objectCredentials);
//
// STEP 1 - Login
//
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
// request.Headers.Add("X-DocuSign-Authentication", authenticateStr);
request.Headers.Add("X-DocuSign-Authentication", jSONCredentialsString);
request.Accept = "application/json";
request.Method = "GET";
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
string responseText = sr.ReadToEnd();
// close stream reader
sr.Close();
JsonTextReader reader = new JsonTextReader(new StringReader(responseText));
JObject jObject = JObject.Parse(responseText);
// get the first User Account data
JToken jUserAccount = jObject["loginAccounts"].First;
// read values from JSON
accountId = (string)jUserAccount["accountId"];
baseURL = (string)jUserAccount["baseUrl"];
//
// STEP 2 - Send Envelope with Information
//
// construct an outgoing JSON request body that create the envelope
string formDataBoundary = String.Format("{0:N}", Guid.NewGuid());
StringBuilder requestBody = new StringBuilder();
string header = string.Format("--{0}\r\nContent-Type: application/json\r\nContent-Disposition: form-data\r\n\r\n", formDataBoundary);
// Documents list to send in the envelope
List<Document> envelopeDocuments = new List<Document>();
Document currentDocument = new Document(1, "ABC.pdf", "C:/Documents/ABC.pdf");
envelopeDocuments.Add(currentDocument);
DocuSignDocument[] documentsArray = (from doc in envelopeDocuments
select new DocuSignDocument()
{
documentId = doc.DocumentID.ToString(),
name = doc.Name
}).ToArray();
//currentDocument = new Document(2, "ABC.pdf", "D:/Documents/ABC.pdf");
//envelopeDocuments.Add(currentDocument);
// creaqte recipients
Recipient firstRecipient = new Recipient()
{
email = "email",
name = "name",
recipientId = 1.ToString(),
routingOrder = 1.ToString(),
tabs = new Tabs()
{
signHereTabs = new List<Tab>()
{ new Tab()
{
documentId = 1.ToString(),
pageNumber = 1.ToString(),
//recipientId = 1.ToString(),
xPosition = 100.ToString(),
yPosition = 100.ToString()
}
}
}
};
List<Recipient> recipients = new List<Recipient>();
recipients.Add(firstRecipient);
// api json attributes setting by developer
// setting attributes for the envelope request
var envelopeAttributes = new
{
//allowReassign = false,
emailBlurb = "EMAIL BODY HERE OK OK",
emailSubject = "EMAIL SUBJECT HERE IS MANDATORY",
// enableWetSign = false,
// messageLock = true,
// notification attributes
/*notifications = new
{
useAccountDefaults = true,
// reminder configuration attributes
reminders = new object[]
{
new
{
reminderEnabled = true,
reminderDelay = 3,
reminderFrequency = 3
}
},
// end reminder configuration attributes
// expiration configuration attributes
expirations = new object[]
{
new
{
expirationEnabled = true,
expirationAfter = 30,
expirationWarn = 5
}
}
}, */
// end notification attributes
status = "sent",
// start documents section
documents = documentsArray,
recipients = new
{
signers = recipients
}
};
// append "/envelopes" to baseURL and use in the request
request = (HttpWebRequest)WebRequest.Create(baseURL + "/envelopes");
request.Headers.Add("X-DocuSign-Authentication", jSONCredentialsString);
request.ContentType = "multipart/form-data; boundary=" + formDataBoundary;
request.Accept = "application/json";
request.Method = "POST";
request.KeepAlive = true;
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
string requestBodyStartStr = header;
requestBodyStartStr += JsonConvert.SerializeObject(envelopeAttributes);
requestBodyStartStr += "\r\n--" + formDataBoundary + "\r\n";
// Write the body of the request
byte[] bodyStart = System.Text.Encoding.UTF8.GetBytes(requestBodyStartStr);
MemoryStream streamBufferData = new MemoryStream();
streamBufferData.Write(bodyStart, 0, bodyStart.Length);
// Read the file contents and write them to the request stream
byte[] buf = new byte[4096];
int length;
FileStream fileStream;
string mixedHeaderBoundary = String.Format("{0:N}", Guid.NewGuid());
// add multipart mixed header
string mixedHeader = "Content-Disposition: form-data\r\n";
mixedHeader += "Content-Type: multipart/mixed; boundary=" + mixedHeaderBoundary + "\r\n\r\n";
byte[] bodyMixedHeader = System.Text.Encoding.UTF8.GetBytes(mixedHeader);
streamBufferData.Write(bodyMixedHeader, 0, bodyMixedHeader.Length);
foreach (Document document in envelopeDocuments)
{
fileStream = null;
// load file from location
fileStream = File.OpenRead(document.PathName);
// write header of pdf
string headerOfDocumentStr = "--" + mixedHeaderBoundary + "\r\n" +
"Content-Type: application/pdf\r\n" +
"Content-Disposition: file; filename=\"" + document.Name + "\";documentId=\"" + document.DocumentID + "\"\r\n\r\n";
byte[] headerDocBytes = System.Text.Encoding.UTF8.GetBytes(headerOfDocumentStr);
streamBufferData.Write(headerDocBytes, 0, headerDocBytes.Length);
length = 0;
while ((length = fileStream.Read(buf, 0, 4096)) > 0)
{
streamBufferData.Write(buf, 0, length);
}
fileStream.Close();
//byte[] bottomMixedBoundaryForFDocument = System.Text.Encoding.UTF8.GetBytes("\r\n--" + mixedHeaderBoundary + "\r\n");
//streamBufferData.Write(bottomMixedBoundaryForFDocument, 0, bottomMixedBoundaryForFDocument.Length);
}
string requestBodyEndStr = "--" + mixedHeaderBoundary + "--\r\n";
byte[] requestBodyEndBytes = System.Text.Encoding.UTF8.GetBytes(requestBodyEndStr);
streamBufferData.Write(requestBodyEndBytes, 0, requestBodyEndBytes.Length);
// write end boundary
requestBodyEndStr = "--" + formDataBoundary + "--";
requestBodyEndBytes = System.Text.Encoding.UTF8.GetBytes(requestBodyEndStr);
streamBufferData.Write(requestBodyEndBytes, 0, requestBodyEndBytes.Length);
// pass temporary buffer data to WebRequestStream
request.ContentLength = streamBufferData.Length;
Stream dataStream = request.GetRequestStream();
byte[] byteArrayToSend = new byte[streamBufferData.Length];
streamBufferData.Seek(0, SeekOrigin.Begin);
streamBufferData.Read(byteArrayToSend, 0, (int)streamBufferData.Length);
dataStream.Write(byteArrayToSend, 0, (int)streamBufferData.Length);
streamBufferData.Close();
// read the response
webResponse = (HttpWebResponse)request.GetResponse();
responseText = "";
sr = new StreamReader(webResponse.GetResponseStream());
responseText = sr.ReadToEnd();
// display results
Console.WriteLine("Response of Action Create Envelope with Two Documents --> \r\n " + responseText);
Console.ReadLine();
}
catch (WebException e)
{
using (WebResponse response = e.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream data = response.GetResponseStream())
{
string text = new StreamReader(data).ReadToEnd();
Console.WriteLine(text);
}
}
Console.ReadLine();
}
}
}
//轉換為JSON的對象中使用的其他類
public class Tab
{
public int documentId { get; set; }
public int pageNumber { get; set; }
public int recipientId { get; set; }
public int xPosition { get; set; }
public int yPosition { get; set; }
public string name { get; set; }
public string tabLabel { get; set; }
}
public class Tabs
{
public List<Tab> signHereTabs { get; set; }
}
public class Recipient
{
public string email { get; set; }
public string name { get; set; }
// public int recipientId { get; set; }
public int routingOrder { get; set; }
public Tabs tabs { get; set; }
}
[EDITED]
//這是來自fiddler的請求體
POST https://demo.docusign.net/restapi/v2/accounts/295724/envelopes HTTP / 1.1 X-DocuSign-Authentication:{“Username”:“email”,“Password”:“username”,“IntegratorKey”: “key”}內容類型:multipart / form-data; boundary = c17efb7771a64f688508187fee57c398接受:application / json主持人:demo.docusign.net內容長度:147201期望:100-continue
--c17efb7771a64f688508187fee57c398 Content-Type:application / json Content-Disposition:form-data
{“emailBlurb”:“EMAIL BODY HERE OK OK”,“emailSubject”:“EMAIL SUBJECT HERE IS MANDATORY”,“status”:“sent”,“documents”:[{“documentId”:1,“name”:“ ABC.pdf “}],” 收件人 “:{” 簽名者 “:[{” 電子郵件 “:” dn@brenock.com”, “名”: “天樞”, “recipientId”: “1”, “routingOrder”: “1”, “選項卡”:{ “signHereTabs”:[{ “documentId”: “1”, “頁面編號”: “1”, “xPosition位置”: “100”, “yPosition”: “100”}]}} ]}} --c17efb7771a64f688508187fee57c398 Content-Disposition:form-data Content-Type:multipart / mixed; 邊界= b670ec35bd824dff8c0eefe62035e0b2
--b670ec35bd824dff8c0eefe62035e0b2 Content-Type:application / pdf Content-Disposition:file; 文件名= “ABC.pdf”; documentId = 1
--b670ec35bd824dff8c0eefe62035e0b2---c17efb7771a64f688508187fee57c398--
我相信問題出在您發送的JSON上。 它是您有效的JSON格式,但您的recipientId的值正在被刪除或未設置。 你有這個為recipientId:
"recipientId": null,
要解決嘗試將此設置為
"recipientId": "1",
或者您想為它設置的任何值,因為它是用戶可配置的。 例如,如果您願意,可以將其設置為“4321”。
此外,DocuSign允許您根據需要設置assignIdID,但如果您根本沒有指定recipientId屬性,DocuSign應該為收件人生成GUID。 因此,我認為解決此問題的另一種方法是根本不包含recipientId
屬性,例如:
"signHereTabs": [
{
"documentId": "1",
"pageNumber": "1",
"xPosition": "100",
"yPosition": "100"
}
]
我相信兩種解決方案都可以解決您的問題
[編輯]
我在Fiddler輸出中看到你添加了一些邊界之間缺少CRLF字符。 這也可能導致您的問題。
如果您要發送兩個文檔,例如它需要采用這種格式。 您看到的每個換行符都是
CRLF (\r\n)
字符。 這是它需要的格式:
--AAA
Content-Type: application/json
Content-Disposition: form-data
<YOUR VALID JSON GOES HERE>
--AAA
Content-Disposition: form-data
Content-Type: multipart/mixed; boundary=BBB
--BBB
Content-Type:application/pdf
Content-Disposition: file; filename=\”document1.pdf"; documentid=1
<PDF Bytes for first document>
--BBB
Content-Type:application/pdf
Content-Disposition: file; filename=\”document2.pdf"; documentid=2
<PDF Bytes for second document>
--BBB--
--AAA--
如果您只發送一個文檔,那么您的間距必須完全如下:
--AAA
Content-Type: application/json
Content-Disposition: form-data
<YOUR VALID JSON GOES HERE>
--AAA
Content-Type:application/pdf
Content-Disposition: file; filename="document.pdf"; documentid=1
<DOCUMENT BYTES GO HERE>
--AAA--
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.