如何通过Adobe Sign API上传已有带标签表单并发起签署(C#/.NET7)
解决方案:使用已有带标签PDF表单通过Adobe Sign API发起签署流程
核心问题说明
你当前的代码调用的是Adobe PDF Services API的DocumentMergeOperation,这是用于从模板生成新文档的服务,和你需要的Adobe Sign API是两个独立的服务,这也是代码无法满足需求的根本原因。
正确操作流程
要使用已有带标签的PDF表单发起签署,流程分为两步:
- 第一步:将现有PDF上传到Adobe Sign,获取文档ID(可选择Transient Documents临时存储,有效期7天;或Library Documents永久存储)
- 第二步:使用该文档ID创建签署协议(Agreement),指定签署人、签署顺序等信息
修复Transient Document上传无响应问题
你之前调用Transient Document API无结果,大概率是请求认证或参数不正确。以下是.NET7中使用HttpClient的正确实现:
using System.Net.Http.Headers; using System.Text; var clientId = Environment.GetEnvironmentVariable("ADOBE_SIGN_CLIENT_ID"); var clientSecret = Environment.GetEnvironmentVariable("ADOBE_SIGN_CLIENT_SECRET"); // 1. 获取Adobe Sign访问令牌 var tokenResponse = await GetAdobeSignAccessToken(clientId, clientSecret); var accessToken = tokenResponse.access_token; // 2. 上传带标签的PDF到Transient Documents var pdfPath = @"C:\Test\Your-Tagged-Form.pdf"; var transientDocId = await UploadTransientDocument(accessToken, pdfPath); Console.WriteLine($"Transient Document ID: {transientDocId}"); // 获取AccessToken的方法 async Task<dynamic> GetAdobeSignAccessToken(string clientId, string clientSecret) { using var client = new HttpClient(); var authString = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{clientId}:{clientSecret}")); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authString); var formData = new Dictionary<string, string> { {"grant_type", "client_credentials"}, {"scope", "user_login:self"} }; var response = await client.PostAsync("https://api.na1.adobe.com/oauth/token", new FormUrlEncodedContent(formData)); response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync<dynamic>(); } // 上传Transient Document的方法 async Task<string> UploadTransientDocument(string accessToken, string filePath) { using var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); using var content = new MultipartFormDataContent(); var fileContent = new ByteArrayContent(File.ReadAllBytes(filePath)); fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/pdf"); content.Add(fileContent, "File", Path.GetFileName(filePath)); var response = await client.PostAsync("https://api.na1.adobe.com/restapi/v6/transientDocuments", content); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync<dynamic>(); return result.transientDocumentId; }
创建签署协议
拿到transientDocId后,即可发起签署请求:
async Task<string> CreateSigningAgreement(string accessToken, string transientDocId) { using var client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var agreementPayload = new { name = "ACH Form Signing Request", participantSetsInfo = new[] { new { memberInfos = new[] { new { email = "signer@example.com" } }, order = 1, role = "SIGNER" } }, documentInfos = new[] { new { transientDocumentId = transientDocId } }, signatureType = "ESIGN", state = "IN_PROCESS" }; var jsonPayload = JsonContent.Create(agreementPayload); var response = await client.PostAsync("https://api.na1.adobe.com/restapi/v6/agreements", jsonPayload); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync<dynamic>(); return result.id; }
关键注意事项
- 确保你的Adobe Sign应用已启用权限:需包含
agreements:write、transientDocuments:write等权限 - 调整API端点:
na1为北美环境,根据你的账号区域替换为eu1(欧洲)、ap1(亚太)等 - 带标签的PDF无需额外处理,Adobe Sign会自动识别表单域
- 若需重复使用表单,可上传为Library Document(永久存储),对应API端点为
/restapi/v6/libraryDocuments
内容的提问来源于stack exchange,提问作者I.M.Groot
相关产品推荐
相关产品推荐

