DocuSign composite templates 中的 prefill text tabs 如何赋值?
如果模板中的字段确实是由发送方填写的 prefill tab,当前代码的赋值上下文就不对:signer.Tabs.TextTabs 操作的是 recipient tabs,无法更新文档级的 prefill tabs。
如果要保留 prefill 字段,可以先创建草稿 envelope,读取文档中的 prefill tabs,按实际 TabId 更新,再发送。如果只是需要程序提前填入公司名称,供收件人查看,也可以将模板字段改为普通 recipient Text tab,通过 inline template 赋值并设置 Locked = "true"。
为什么 TabLabel 一致仍然没有生效?
DocuSign 中,“提前填写字段值”和“字段类型是 prefill”是两个不同的概念:
| 字段 | 归属 | 赋值位置 |
|---|---|---|
| 普通 recipient Text tab | 某个 signer 或模板角色 | recipients.signers[].tabs.textTabs |
| 发送方 prefill Text tab | 文档,不关联 recipient | 文档 tabs 中的 prefillTabs.textTabs |
DocuSign 官方说明指出,prefill fields 不关联任何 recipient,字段值由发送方设置。参见 DocuSign prefill fields 说明。
把字段放到相同 recipient 上,或添加一个包含 signer.Tabs 的 inline template,都不会改变字段归属。即使 TabLabel 相同,也不能跨这两种上下文更新字段。
PreFillLegalCompanyName_GUID 只是 anchor string。名称中的 PreFill 前缀不能证明它是 prefill tab,应检查 API 返回的实际字段结构。
方案一:保留 prefill tabs,创建草稿后更新
这条路径适合仍需使用发送方字段的模板。
- 使用现有 composite templates 创建 envelope,将
Status设为"created"。 - 获取生成后的 envelope 的实际 document IDs。
- 调用
GetDocumentTabs,检查PrefillTabs.TextTabs。 - 在目标文档内按
TabLabel找到字段,再使用返回的TabId更新值。 - 确认填充值正确后,将 envelope 状态改为
"sent"。
DocuSign 开发者支持给出的 prefill 更新示例使用文档 tabs 接口,将更新体放在 prefillTabs.textTabs 下,并提供目标字段的 tabId。参见官方支持示例。
对应的 REST 请求为:
GET /v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId}/tabs
取得字段 ID 后更新:
PUT /v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId}/tabs
Content-Type: application/json
{
"prefillTabs": {
"textTabs": [
{
"tabId": "<tabId returned by GET>",
"value": "Test Customer LLC"
}
]
}
}
C# 示例
以下示例假设 envelopesApi 已完成认证,envelopeDefinition 已包含现有的 composite templates 和收件人配置。documentId 必须取自生成后的 envelope。
using System;
using System.Linq;
using DocuSign.eSign.Model;
// 先创建草稿,避免收件人在赋值完成前收到文档。
envelopeDefinition.Status = "created";
var result = envelopesApi.CreateEnvelope(accountId, envelopeDefinition);
var envelopeId = result.EnvelopeId;
var documentTabs = envelopesApi.GetDocumentTabs(
accountId, envelopeId, documentId);
var matches = documentTabs.PrefillTabs?.TextTabs?
.Where(tab => string.Equals(
tab.TabLabel,
"LegalCompanyName",
StringComparison.Ordinal))
.ToList();
if (matches == null || matches.Count == 0)
{
throw new InvalidOperationException(
"No matching prefill text tab was found in the document.");
}
var update = new Tabs
{
PrefillTabs = new PrefillTabs
{
TextTabs = matches.Select(tab => new Text
{
TabId = tab.TabId,
Value = "Test Customer LLC"
}).ToList()
}
};
envelopesApi.UpdateDocumentTabs(
accountId, envelopeId, documentId, update);
// 发送前重新读取,确认目标字段已更新。
var verified = envelopesApi.GetDocumentTabs(
accountId, envelopeId, documentId);
var updatedIds = verified.PrefillTabs?.TextTabs?
.Where(tab => tab.Value == "Test Customer LLC")
.Select(tab => tab.TabId)
.ToHashSet();
if (updatedIds == null ||
matches.Any(tab => !updatedIds.Contains(tab.TabId)))
{
throw new InvalidOperationException("Prefill verification failed.");
}
envelopesApi.Update(accountId, envelopeId, new Envelope
{
Status = "sent"
});
示例会更新该文档中所有同名的 prefill Text tabs。如果同名字段代表不同业务数据,应增加筛选条件,或使用唯一的字段标签。相关方法及参数可查阅 C# EnvelopesApi 文档。
如果草稿中没有目标 prefill tab,也就没有可更新的 TabId。此时需要检查模板字段是否被带入;必要时,在草稿上通过 CreateDocumentTabs 创建带位置或 anchor 信息的 prefill tab,并同时设置值。不要直接用模板中的字段 ID 更新生成后的 envelope。
方案二:使用锁定的普通 recipient Text tab
如果公司名称完全由程序提供,可以在模板中使用普通 Text tab,并将其分配给正确的 signer 角色。之后在同一 composite template 的 inline template 中设置:
signer.Tabs = new Tabs
{
TextTabs = new System.Collections.Generic.List<Text>
{
new Text
{
TabLabel = "LegalCompanyName",
Value = "Test Customer LLC",
Locked = "true"
}
}
};
使用这条路径前,必须先修改模板中的字段归属。仅在现有代码中增加 Locked,不会将原来的 sender prefill tab 转换为 recipient tab。
需要核对以下配置:
signer.RoleName与 server template 中的目标角色一致。- inline template 中的 signer 与模板角色正确合并。
- 模板字段确实属于该角色,且
TabLabel一致。 - 覆盖字段值的 inline template 在模板应用顺序中位于 server template 之后。例如 server template 使用
Sequence = "1",inline template 使用Sequence = "2"。
DocuSign 的 composite templates 官方示例展示了按 tabLabel 设置普通文本字段值并锁定的做法。
anchor-based tabs 是否需要特殊赋值?
anchor 决定字段放在哪里,字段归属决定通过哪个接口赋值。
对于已经生成的 prefill tab,先找到它的 TabId,再更新 Value,通常不需要重新提交 AnchorString。对于普通 recipient Text tab,官方 composite templates 示例支持通过匹配 TabLabel 提供值。
原问题尚未提供完整请求和 tabs 查询响应,不能仅凭现有片段确认模板中的实际字段类型。应先查看目标字段出现在文档的 prefillTabs.textTabs 中,还是某个 recipient 的 textTabs 中,再选择对应路径。PDF annotations 的转换过程也应保留正确的字段归属;字段已经显示在文档上,并不能说明赋值请求命中了它。
备注:内容仅供参考。
