so i want to check if itext (version 8) is good for me needs
i need to add sign fields and based on them lock some other fields in acro form,
so i have it like :
PdfWriter writer = new PdfWriter("AddSignFieldItext77.pdf");
iText.Kernel.Pdf.PdfDocument pdf = new iText.Kernel.Pdf.PdfDocument(writer);
var newPage = pdf.AddNewPage(new PageSize(PageSize.A4));
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdf, true);
var formRectangle = new iText.Kernel.Geom.Rectangle(100, 800, 200, 20);
var formFieldBuilder = new TextFormFieldBuilder(pdf, "TextFormField1");
formFieldBuilder.SetPage(newPage);
formFieldBuilder.SetWidgetRectangle(formRectangle);
var formfield = formFieldBuilder.CreateText();
form.AddField(formfield);
var formRectangle2 = new iText.Kernel.Geom.Rectangle(100, 700, 200, 20);
var formFieldBuilder2 = new TextFormFieldBuilder(pdf, "TextFormField2");
formFieldBuilder2.SetPage(newPage);
formFieldBuilder2.SetWidgetRectangle(formRectangle2);
var formfield2 = formFieldBuilder2.CreateText();
form.AddField(formfield2);
var signatureRectangle1 = new iText.Kernel.Geom.Rectangle(36, 448, 200, 100);
var signatureField1 = new SignatureFormFieldBuilder(pdf, "SignField1");
signatureField1.SetPage(newPage);
signatureField1.SetWidgetRectangle(signatureRectangle1);
PdfSignatureFormField sig1 = signatureField1.CreateSignature();
PdfSigFieldLock pdfSigFieldLock1 = new PdfSigFieldLock();
string[] fieldToLock1 = new string[] { "TextFormField1" };
pdfSigFieldLock1.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE, fieldToLock1);
PdfDictionary dict = sig1.GetPdfObject();
dict.Put(PdfName.Lock,pdfSigFieldLock1.GetPdfObject());
form.AddField(sig1);
var signatureRectangle2 = new iText.Kernel.Geom.Rectangle(36, 248, 200, 100);
var signatureField2 = new SignatureFormFieldBuilder(pdf, "SignField2");
signatureField2.SetPage(newPage);
signatureField2.SetWidgetRectangle(signatureRectangle2);
PdfSignatureFormField sig2 = signatureField2.CreateSignature();
PdfSigFieldLock pdfSigFieldLock2 = new PdfSigFieldLock();
string[] fieldToLock2 = new string[] { "TextFormField2", };
pdfSigFieldLock2.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE,fieldToLock2 );
PdfDictionary dict2 = sig2.GetPdfObject();
dict2.Put(PdfName.Lock, pdfSigFieldLock2.GetPdfObject());
form.AddField(sig2);
pdf.Close();
and this works almost fine - produces pdf like this
And i can sign 1st field. it is fine. saved , signed , TextFormField1
locked.
And then if i want sign second field - i get error as on screenshot that function parrameter had an incorrect value?
If i close and re-open document - i can sign in this SignField2
without error
but i do not want to have to close and re-open doc for second sign
please advice how to fix this - am i missing something here? is there better approach?
best regards
Indeed, Adobe Acrobat (at least the version 2023.001.20174 I use currently) runs into an issue when you try to sign both signature fields in a single session.
At first inspection no errors in the PDF could be identified. Thus, I created a similar file using Adobe Acrobat itself and observed that Adobe Acrobat does not run into the same issue with that. Then I determined the differences and tried to find out which differences are relevant.
As it turns out, there is only one relevant difference: If the signature field dictionaries have a correct Type entry, Adobe Acrobat can sign both PDF signature fields in a single session. iText, on the other hand, does not add a Type entry by default.
As the Type entry is specified as optional and as there is only one allowed value for it in case of signature field dictionaries, this clearly can be considered an Adobe Acrobat bug.
As a work-around you can add the type explicitly using iText like this:
...
PdfSigFieldLock pdfSigFieldLock1 = new PdfSigFieldLock();
string[] fieldToLock1 = new string[] { "TextFormField1" };
pdfSigFieldLock1.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE, fieldToLock1);
PdfDictionary dict = sig1.GetPdfObject();
dict.Put(PdfName.Type, PdfName.Annot); // <-----
dict.Put(PdfName.Lock, pdfSigFieldLock1.GetPdfObject());
form.AddField(sig1);
...
PdfSigFieldLock pdfSigFieldLock2 = new PdfSigFieldLock();
string[] fieldToLock2 = new string[] { "TextFormField2", };
pdfSigFieldLock2.SetFieldLock(PdfSigFieldLock.LockAction.INCLUDE, fieldToLock2);
PdfDictionary dict2 = sig2.GetPdfObject();
dict2.Put(PdfName.Type, PdfName.Annot); // <-----
dict2.Put(PdfName.Lock, pdfSigFieldLock2.GetPdfObject());
form.AddField(sig2);
...