【问题标题】:Embed DocuSign Signing Experience in a .NET Application在 .NET 应用程序中嵌入 DocuSign 签名体验
【发布时间】:2013-12-26 09:28:26
【问题描述】:

我正在使用 .NET Web 应用程序(Web 表单)。我需要将文档签名体验嵌入到我的 Web 应用程序中,最好是通过 Iframe。

是否可以从 Web 应用程序进行身份验证以进行文档签名,然后将签名体验带入 iframe?

还可以在签名完成、签名被拒绝、窗口关闭等时重定向到自定义 URL?

【问题讨论】:

  • 提供“DocuSign 电子签名”以给出答案和解决方案的公司不是更好吗?
  • @Aristos:我已经标记了有问题的docusign。
  • 我们正在这样做,但突然在 iOS 上,我们在 iFrame 中遇到了问题(可能是 CORS 问题)。 DocuSign 支持表示他们不支持 iFrame。所以做实际的重定向似乎是正确的解决方案。

标签: asp.net iframe docusignapi


【解决方案1】:

这是一份关于如何在 C# 中进行嵌入式签名的 API 演练副本。您可以在此处找到其他演练:http://iodocs.docusign.com/APIWalkthroughs

下面的代码应该完全符合您的要求 - 为您提供经过身份验证的 IFRAME,以供签名。在使用它之前,您应该为您的文档创建一个模板,并将签名选项卡放在您希望某人签名的位置。

// DocuSign API Walkthrough 08 in C# - Embedded Signing

// To run this sample: 
//  1) Create a new .NET project.
//  2) Add 3 assembly references to the project:  System, System.Net, and System.XML
//  3) Update the username, password, integrator key, and templateId in the code
//  4) Compile and Run
//
using System; 
using System.IO; 
using System.Net;
using System.Xml;
using System.Text;

namespace APIWalkthrough08 
{
    public class EmbeddedSigning
    {
        // Enter your info:
        static string username = "***";
        static string password = "***";
        static string integratorKey = "***";
        static string templateId = "***";
        static string roleName = "***";

        public static void Main ()
        {
            string url = "https://demo.docusign.net/restapi/v2/login_information";
            string baseURL = "";    // we will retrieve this
            string accountId = "";  // will retrieve
            string envelopeId = ""; // will retrieve
            string uri = "";    // will retrieve

            string authenticateStr = 
                "<DocuSignCredentials>" + 
                    "<Username>" + username + "</Username>" +
                    "<Password>" + password + "</Password>" + 
                    "<IntegratorKey>" + integratorKey + "</IntegratorKey>" + 
                    "</DocuSignCredentials>";

            // 
            // STEP 1 - Login
            //
            try {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
                request.Headers.Add ("X-DocuSign-Authentication", authenticateStr);
                request.Accept = "application/xml";
                request.Method = "GET";
                HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse ();
                StreamReader sr = new StreamReader(webResponse.GetResponseStream());
                string responseText = sr.ReadToEnd();
                using (XmlReader reader = XmlReader.Create(new StringReader(responseText))) {
                    while (reader.Read()) { // Parse the xml response body
                        if((reader.NodeType == XmlNodeType.Element) && (reader.Name == "accountId"))
                            accountId = reader.ReadString();
                        if((reader.NodeType == XmlNodeType.Element) && (reader.Name == "baseUrl"))
                            baseURL = reader.ReadString();
                    }
                }

                //--- display results
                Console.WriteLine("accountId = " + accountId + "\nbaseUrl = " + baseURL);

                //
                // STEP 2 - Request Envelope Result
                //

                // Construct an outgoing XML request body
                string requestBody = "<envelopeDefinition xmlns=\"http://www.docusign.com/restapi\">" + 
                    "<accountId>" + accountId + "</accountId>" + 
                        "<status>sent</status>" + 
                        "<emailSubject>API Call for Embedded Sending</emailSubject>" + 
                        "<emailBlurb>This comes from C#</emailBlurb>" + 
                        "<templateId>" + templateId + "</templateId>" + 
                        "<templateRoles>" + 
                        "<templateRole>" + 
                        "<email>" + username + "</email>" + // NOTE: Use different email address if username provided in non-email format!
                        "<name>Name</name>" +               // username can be in email format or an actual ID string
                        "<roleName>" + roleName + "</roleName>" +
                        "<clientUserId>1</clientUserId>" +
                        "</templateRole>" + 
                        "</templateRoles>" + 
                        "</envelopeDefinition>";

                // append "/envelopes" to baseUrl and use in the request
                request = (HttpWebRequest)WebRequest.Create (baseURL + "/envelopes");
                request.Headers.Add ("X-DocuSign-Authentication", authenticateStr);
                request.ContentType = "application/xml";
                request.Accept = "application/xml";
                request.ContentLength = requestBody.Length;
                request.Method = "POST";
                // write the body of the request
                byte[] body = System.Text.Encoding.UTF8.GetBytes (requestBody);
                Stream dataStream = request.GetRequestStream ();
                dataStream.Write (body, 0, requestBody.Length);
                dataStream.Close ();
                // read the response
                webResponse = (HttpWebResponse)request.GetResponse();
                sr = new StreamReader(webResponse.GetResponseStream());
                responseText = sr.ReadToEnd();
                using (XmlReader reader = XmlReader.Create(new StringReader(responseText))) {
                    while (reader.Read()) { // Parse the xml response body
                        if((reader.NodeType == XmlNodeType.Element) && (reader.Name == "envelopeId"))
                            envelopeId = reader.ReadString();
                        if((reader.NodeType == XmlNodeType.Element) && (reader.Name == "uri"))
                            uri = reader.ReadString();
                    }
                }

                //--- display results
                Console.WriteLine("Envelope sent!.  EnvelopeId is --> " + envelopeId);

                //
                // STEP 3 - Get the Embedded Console Sign View
                //

                // construct another outgoing XML request body
                string reqBody = "<recipientViewRequest xmlns=\"http://www.docusign.com/restapi\">"  +
                    "<authenticationMethod>email</authenticationMethod>" + 
                        "<email>" + username + "</email>" +     // NOTE: Use different email address if username provided in non-email format!
                        "<returnUrl>http://www.docusign.com</returnUrl>" +  // username can be in email format or an actual ID string
                        "<clientUserId>1</clientUserId>" + 
                        "<userName>Name</userName>" + 
                        "</recipientViewRequest>";

                // append uri + "/views/recipient" to baseUrl and use in the request
                request = (HttpWebRequest)WebRequest.Create (baseURL + uri + "/views/recipient");
                request.Headers.Add ("X-DocuSign-Authentication", authenticateStr);
                request.ContentType = "application/xml";
                request.Accept = "application/xml";
                request.ContentLength = reqBody.Length;
                request.Method = "POST";
                // write the body of the request
                byte[] body2 = System.Text.Encoding.UTF8.GetBytes (reqBody);
                Stream dataStream2 = request.GetRequestStream ();
                dataStream2.Write (body2, 0, reqBody.Length);
                dataStream2.Close ();
                // read the response
                webResponse = (HttpWebResponse)request.GetResponse();
                sr = new StreamReader(webResponse.GetResponseStream());
                responseText = sr.ReadToEnd();
                using (XmlReader reader = XmlReader.Create(new StringReader(responseText))) {
                    while (reader.Read()) { // Parse the xml response body
                        if((reader.NodeType == XmlNodeType.Element) && (reader.Name == "url"))
                            url = reader.ReadString();
                    }
                }
                Console.WriteLine("Embeded View Result --> " + responseText);
                System.Diagnostics.Process.Start(url);
            }
            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);
                    }
                }
            }
        } // end main()
    } // end class
} // end namespace

【讨论】:

    【解决方案2】:

    如果您还没有这样做,我建议您查看 DocuSign REST API 指南:http://www.docusign.com/sites/default/files/REST_API_Guide_v2.pdf - 因为它包含实现目标所需的所有信息(比我更详细在这里描述)。

    要通过 REST API 创建/发送信封,您将使用POST /accounts/{accountId}/envelopes,如 API 指南的“发送信封或创建草稿信封”部分所述。对于您希望在应用程序中嵌入/强制签名的每个收件人,请务必为收件人设置 clientUserId 属性 - 创建信封请求中收件人的此属性的存在是什么告诉 DocuSign 您的应用程序将启动/促进收件人的签名体验(因此 DocuSign 不会向收件人发送签名邀请电子邮件)。

    当收件人在您的应用程序中查看/签署信封时,您将使用POST /accounts/{accountId}/envelopes/{envelopeId}/views/recipient,如 API 指南的“POST Recipient View”部分所述——检索可用于启动/启动收件人的 DocuSign 签名会话的 URL。使用此 URL 作为 iFrame 的目标将在框架内显示 DocuSign 签名会话。在 POST Recipient View 请求中,您设置 returnUrl 属性以指示 DocuSign 在嵌入/强制签名会话完成时应将签名者重定向到何处。 DocuSign 将在重定向到此 URL 时附加一个查询字符串参数(“事件”),该参数的值将指示签名会话的结果。 API 指南第 167 页上的 returnUrl 参数说明列出了此参数的可能值。您的应用程序(即您指定的重定向页面)可以询问此参数值以了解签名会话的结果,并采取任何必要的操作。

    关于身份验证——用于验证信封发件人的信息是通过每个 API 请求的 X-DocuSign-Authentication 标头提供的。此外,可以为每个收件人指定特定形式的身份验证——例如,访问代码、电话身份验证、ID 检查、SMS 身份验证——您可以通过在“创建信封”请求。 (API 指南包含有关这些属性的信息。)

    【讨论】:

    • 就身份验证而言,This page 上的注释说您可以存储 baseurl 和 apiPassword。这是否意味着在提供 apipassword 的请求中不需要 X-DocuSign-Authentication 标头?如果是这样,您能否提供指向如何更详细地执行此操作的页面的链接?如果不是,您能解释一下存储 apiPassword 的好处吗?
    • 每个 API 请求都需要 X-DocuSign-Authentication 标头——这就是 DocuSign 识别集成应用程序(和成员帐户)并确定请求是否被授权的方式。 “login_information”请求用于检索构建 X-DocuSign-Authentication 标头所需的信息——但由于该信息不会经常更改,注释只是说您的应用程序可以进行一次“login_information”调用,然后保存/缓存响应中的信息,然后简单地重新使用它来为每个后续请求形成 X-DocuSign-Authentication 标头。
    • 所以每个对 Docusign 的请求都必须有一个类似这样的标头:&lt;DocuSignCredentials&gt;&lt;Username&gt;username&lt;/Username&gt;&lt;Password&gt;password&lt;/Password&gt;&lt;IntegratorKey&gt;integratorKey&lt;/IntegratorKey&gt;&lt;/DocuSignCredentials&gt;?
    • 是的,对 DocuSign 的每个请求都必须包含“集成商密钥”以及身份验证凭据(用户名、密码等)。 X-DocuSign-Authentication 标头可能看起来像您发布的内容 - 但可能看起来有些不同,具体取决于您验证请求的方式(例如,使用“Send-On-Behalf-Of”或使用“oAuth " 或仅使用您在之前评论中显示的常规身份验证。)
    • 好吧,这很简单,但是文档中提到的 apiPassword 的目的是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多