Search code examples
docusignapi

How to upload image signature in docusign by c#?


I want to upload an image to docusign by c#, but it does not work. Below is my code that I wrote with mvc4.

Please help me, Thanks!

public class UploadFileController : Controller
{
    static string email = "***";            // your account email
    static string password = "***";         // your account password
    static string integratorKey = "***";        // your account Integrator Key (found on Preferences -> API page)
    static string baseURL = "";         // - we will retrieve this
    static string accountId = "***";            // - we will retrieve this
    static string userId = "***";
    static string signatureName = "signature";

    #region FormUpload
    public static class FormUpload
    {
        private static readonly Encoding encoding = Encoding.UTF8;
        public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters)
        {
            string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
            string contentType = "multipart/form-data; boundary=" + formDataBoundary;

            byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);

            return PostForm(postUrl, userAgent, contentType, formData);
        }
        private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
        {
            HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;

            if (request == null)
            {
                throw new NullReferenceException("request is not a http request");
            }

            // Set up the request properties.
            request.Method = "PUT";
            request.ContentType = contentType;
           // request.UserAgent = userAgent;
            request.CookieContainer = new CookieContainer();
            request.ContentLength = formData.Length;
            string authenticateStr =
          "<DocuSignCredentials>" +
              "<Username>" + email + "</Username>" +
              "<Password>" + password + "</Password>" +
              "<IntegratorKey>" + integratorKey + "</IntegratorKey>" + // global (not passed)
              "</DocuSignCredentials>";
            request.Headers.Add("X-DocuSign-Authentication", authenticateStr);

            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(formData, 0, formData.Length);
                requestStream.Close();
            }

            return request.GetResponse() as HttpWebResponse;
        }

        private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
        {
            Stream formDataStream = new System.IO.MemoryStream();
            bool needsCLRF = false;

            foreach (var param in postParameters)
            {
                // Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
                // Skip it on the first parameter, add it to subsequent parameters.
                if (needsCLRF)
                    formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));

                needsCLRF = true;

                if (param.Value is FileParameter)
                {
                    FileParameter fileToUpload = (FileParameter)param.Value;

                    // Add just the first part of this param, since we will write the file data directly to the Stream
                    StringBuilder headerbuilder = new StringBuilder();
                    String header1, header2, header3, header4, header5, header6, header7, header8, header9, header10, header11, header12, header13;
                    header1 = String.Format("--{0}\r\nContent-Disposition: form-data; name =\"HTTPMethod\"", boundary);
                    header2 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"MethodName\"", boundary);
                    header3 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"MethodURI\"", boundary);
                    header4 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"BaseURL\"", boundary);
                    header5 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"PublicPath\"", boundary);
                    header6 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"Protocol\"", boundary);
                    header7 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"Version\"", boundary);
                    header8 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"Username\"", boundary);
                    header9 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"Password\"", boundary);
                    header10 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"IntegratorKey\"", boundary);
                    header11 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"pram[accountId]\"", boundary);
                    header12 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"param[userId]\"", boundary);
                    header13 = String.Format("\n--{0}\r\nContent-Disposition: form-data; name =\"signatureName\"", boundary);
                    //headerbuilder.Append(

                    string header = string.Format("\n--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
                        boundary,
                        param.Key,
                        fileToUpload.FileName ?? param.Key,
                        fileToUpload.ContentType ?? "application/octet-stream");

                    headerbuilder.Append(header1);
                    headerbuilder.Append(header2);
                    headerbuilder.Append(header3);
                    headerbuilder.Append(header4);
                    headerbuilder.Append(header5);
                    headerbuilder.Append(header6);
                    headerbuilder.Append(header7);
                    headerbuilder.Append(header8);
                    headerbuilder.Append(header9);
                    headerbuilder.Append(header10);
                    headerbuilder.Append(header11);
                    headerbuilder.Append(header12);
                    headerbuilder.Append(header13);
                    headerbuilder.Append(header);

                    String a = headerbuilder.ToString();
                    formDataStream.Write(encoding.GetBytes(headerbuilder.ToString()), 0, encoding.GetByteCount(headerbuilder.ToString()));

                    // Write the file data directly to the Stream, rather than serializing it to a string.
                    formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
                }
                else
                {
                    string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
                        boundary,
                        param.Key,
                        param.Value);
                    formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
                }
            }

            // Add the end of the request.  Start with a newline
            string footer = "\r\n--" + boundary + "--\r\n";
            formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));

            // Dump the Stream into a byte[]
            formDataStream.Position = 0;
            byte[] formData = new byte[formDataStream.Length];
            formDataStream.Read(formData, 0, formData.Length);
            formDataStream.Close();

            return formData;
        }

        public class FileParameter
        {
            public byte[] File { get; set; }
            public string FileName { get; set; }
            public string ContentType { get; set; }
            public FileParameter(byte[] file) : this(file, null) { }
            public FileParameter(byte[] file, string filename) : this(file, filename, null) { }
            public FileParameter(byte[] file, string filename, string contenttype)
            {
                File = file;
                FileName = filename;
                ContentType = contenttype;
            }
        }
    }
    #endregion

    public ActionResult Index()
    {


        // Read file data
        FileStream fs = new FileStream("D:\\signature3.jpg", FileMode.Open, FileAccess.Read);
        byte[] data = new byte[fs.Length];
        fs.Read(data, 0, data.Length);
        fs.Close();

        // Generate post objects
        Dictionary<string, object> postParameters = new Dictionary<string, object>();
        postParameters.Add("filename", "signature3.jpg");
        postParameters.Add("fileformat", "jpg");
        postParameters.Add("file", new FormUpload.FileParameter(data, "signature3.jpg", "image/jpg"));

        // Create request and receive response
        string postURL = "https://demo.docusign.net/restapi/v2/accounts/"+accountId+"/users/"+userId+"/signatures/"+signatureName+"/signature_image";

        string userAgent = "Someone";
        HttpWebResponse webResponse = FormUpload.MultipartFormDataPost(postURL, userAgent, postParameters);

        // Process response
        StreamReader responseReader = new StreamReader(webResponse.GetResponseStream());
        string fullResponse = responseReader.ReadToEnd();
        webResponse.Close();
        Response.Write(fullResponse);
        return View();
    }

}

Solution

  • DocuSign imposes a 200K limit on signature image files. See the DocuSign REST API guide for more info. Page 247 describes the set signature image call:

    http://docusign.com/sites/default/files/REST_API_Guide_v2.pdf