How to search signatures with predicate functions
Leave feedback
On this page
Search with Predicate Functions
Overview
The GroupDocs.Signature library provides enhanced Search methods that accept predicate functions (Func<BaseSignature, bool>) to filter signatures based on custom criteria. This allows you to perform more flexible and targeted signature searches by applying custom filtering logic to the search results.
Benefits
Flexible Filtering: Filter signatures based on any custom criteria using lambda expressions
Search First: All signatures matching the search options are found (or all signatures if no options provided)
Filter Results: The predicate is applied to filter the search results
Return Filtered Results: Only signatures matching the predicate are returned
Examples
Example 1: Search and Filter by Text Content
usingGroupDocs.Signature;usingGroupDocs.Signature.Options;usingGroupDocs.Signature.Domain;using(Signaturesignature=newSignature("document.pdf")){// Search for text signaturesList<SearchOptions>searchOptions=newList<SearchOptions>{newTextSearchOptions()};// Filter to only signatures containing "Approved"SearchResultresult=signature.Search(searchOptions,sig=>sigisTextSignaturetextSig&&textSig.Text.Contains("Approved"));foreach(BaseSignaturesiginresult.Signatures){Console.WriteLine($"Found: {((TextSignature)sig).Text}");}}
Example 2: Search All Signature Types with Filtering
using(Signaturesignature=newSignature("document.pdf")){// Search all signature types and filter by typeList<BaseSignature>result=signature.Search(sig=>sig.SignatureType==SignatureType.Digital);Console.WriteLine($"Found {result.Count} digital signatures");}
Example 3: Search and Filter by Multiple Criteria
using(Signaturesignature=newSignature("document.pdf")){List<SearchOptions>searchOptions=newList<SearchOptions>{newTextSearchOptions(),newBarcodeSearchOptions()};// Filter signatures by page and typeSearchResultresult=signature.Search(searchOptions,sig=>sig.PageNumber==1&&(sig.SignatureType==SignatureType.Text||sig.SignatureType==SignatureType.Barcode));Console.WriteLine($"Found {result.Signatures.Count} signatures on page 1");}
Example 4: Search Signatures by Date Range
using(Signaturesignature=newSignature("document.pdf")){DateTimestartDate=newDateTime(2024,1,1);DateTimeendDate=newDateTime(2024,12,31);// Search and filter by signature dateList<BaseSignature>result=signature.Search(sig=>sig.SignDate.HasValue&&sig.SignDate.Value>=startDate&&sig.SignDate.Value<=endDate);Console.WriteLine($"Found {result.Count} signatures in 2024");}
Example 5: Search and Filter by Signature Size
using(Signaturesignature=newSignature("document.pdf")){List<SearchOptions>searchOptions=newList<SearchOptions>{newImageSearchOptions()};// Filter image signatures by sizeSearchResultresult=signature.Search(searchOptions,sig=>{if(sigisImageSignatureimgSig){returnimgSig.Width>200&&imgSig.Height>200;}returnfalse;});Console.WriteLine($"Found {result.Signatures.Count} large image signatures");}
Example 6: Find Signatures in Specific Region
using(Signaturesignature=newSignature("document.pdf")){// Define a region (rectangle)intregionLeft=100;intregionTop=100;intregionWidth=200;intregionHeight=200;List<BaseSignature>result=signature.Search(sig=>sig.Left>=regionLeft&&sig.Top>=regionTop&&sig.Left+sig.Width<=regionLeft+regionWidth&&sig.Top+sig.Height<=regionTop+regionHeight);Console.WriteLine($"Found {result.Count} signatures in the specified region");}
Example 7: Search Signatures with Specific Properties
using(Signaturesignature=newSignature("document.pdf")){List<SearchOptions>searchOptions=newList<SearchOptions>{newQRCodeSearchOptions()};// Search for QR codes with specific dataSearchResultresult=signature.Search(searchOptions,sig=>{if(sigisQrCodeSignatureqrSig){returnqrSig.Text.StartsWith("https://")||qrSig.Text.Contains("contract-id:");}returnfalse;});foreach(QrCodeSignatureqrSiginresult.ToList<QrCodeSignature>()){Console.WriteLine($"QR Code: {qrSig.Text}");}}
Example 8: Search by Signature Type and Page
using(Signaturesignature=newSignature("document.pdf")){// Search all signatures and filter by type and pageList<BaseSignature>result=signature.Search(sig=>sig.SignatureType==SignatureType.Text&&sig.PageNumber==1);Console.WriteLine($"Found {result.Count} text signatures on page 1");}
Common Use Cases
1. Find Signatures by Author
using(Signaturesignature=newSignature("document.pdf")){DigitalSearchOptionssearchOptions=newDigitalSearchOptions();List<BaseSignature>result=signature.Search(newList<SearchOptions>{searchOptions},sig=>sigisDigitalSignaturedigitalSig&&digitalSig.SignerName=="John Doe");Console.WriteLine($"Found {result.Count} signatures by John Doe");}
using(Signaturesignature=newSignature("document.pdf")){// Find signatures in bottom-right corner that are largeList<BaseSignature>result=signature.Search(sig=>sig.Left>400&&sig.Top>600&&sig.Width>150&&sig.Height>50);Console.WriteLine($"Found {result.Count} large signatures in bottom-right");}
4. Search Multiple Signature Types with Complex Filtering
using(Signaturesignature=newSignature("document.pdf")){List<SearchOptions>searchOptions=newList<SearchOptions>{newTextSearchOptions(),newImageSearchOptions(),newQRCodeSearchOptions()};// Find signatures that are either text with specific content, // or QR codes with URLs, or large imagesSearchResultresult=signature.Search(searchOptions,sig=>{if(sigisTextSignaturetextSig){returntextSig.Text.Contains("APPROVED");}if(sigisQrCodeSignatureqrSig){returnqrSig.Text.StartsWith("http");}if(sigisImageSignatureimgSig){returnimgSig.Width>300&&imgSig.Height>300;}returnfalse;});Console.WriteLine($"Found {result.Signatures.Count} matching signatures");}
Best Practices
1. Use Specific Predicates
Good:
// Specific and clear predicateSearchResultresult=signature.Search(searchOptions,sig=>sigisTextSignaturetextSig&&textSig.Text=="Approved");
Avoid:
// Too generic, might match unintended signaturesList<BaseSignature>result=signature.Search(sig=>true);
2. Handle Null Checks
// Safe predicate with null checksSearchResultresult=signature.Search(searchOptions,sig=>{if(sig==null)returnfalse;if(sigisTextSignaturetextSig){return!string.IsNullOrEmpty(textSig.Text)&&textSig.Text.Contains("Contract");}returnfalse;});
3. Combine Multiple Conditions
// Clear, readable predicate with multiple conditionsSearchResultresult=signature.Search(searchOptions,sig=>sig.PageNumber==1&&sig.SignatureType==SignatureType.Text&&sigisTextSignaturetextSig&&textSig.Text.Length>10);
// Good: Use specific search options to narrow down initial searchList<SearchOptions>searchOptions=newList<SearchOptions>{newTextSearchOptions{Text="Contract"}};// Then apply additional filtering with predicateSearchResultresult=signature.Search(searchOptions,sig=>sig.PageNumber==1);
Error Handling
Null Parameter Validation
The methods throw ArgumentNullException if required parameters are null:
try{using(Signaturesignature=newSignature("document.pdf")){// This will throw ArgumentNullExceptionSearchResultresult=signature.Search(null,sig=>true);}}catch(ArgumentNullExceptionex){Console.WriteLine($"Error: {ex.Message}");}
Safe Usage Pattern
using(Signaturesignature=newSignature("document.pdf")){if(searchOptions!=null&&predicate!=null){SearchResultresult=signature.Search(searchOptions,predicate);// Process results}}
Return Values
Search(List<SearchOptions>, Func<...>): Returns SearchResult - Contains filtered signatures and metadata (processing time, document size, etc.)
Search(Func<...>): Returns List<BaseSignature> - A list of filtered signatures
Empty Results: Returns empty collection if no signatures match the predicate
// Get all search resultsSearchResultresult=signature.Search(searchOptions);List<BaseSignature>allSignatures=result.Signatures;// Manual filteringList<BaseSignature>filtered=allSignatures.Where(sig=>sig.PageNumber==1).ToList();
With Predicate
// Filtered during search (more concise)SearchResultresult=signature.Search(searchOptions,sig=>sig.PageNumber==1);List<BaseSignature>filtered=result.Signatures;
Advantages:
More concise code
Cleaner API
Single method call instead of search + filter
Summary
The predicate-based Search methods provide a powerful and flexible way to search for signatures in GroupDocs.Signature. They allow you to:
Filter signatures based on any custom criteria
Search across all signature types or specific types
Write more readable and maintainable code
Handle complex filtering scenarios with ease
Use these methods when you need to find a subset of signatures based on specific criteria, rather than searching all signatures and filtering manually.
More resources
GitHub Examples
You may easily run the code above and see the feature in action in our GitHub examples: