Starting with GroupDocs.Conversion for .NET v24.10, all delegate-based patterns use Context Objects. These objects provide rich information about the conversion process and enable dynamic, context-aware conversion configurations.
Context objects are foundational to understanding how delegates work in GroupDocs.Conversion. If you see patterns like Func<LoadContext, LoadOptions> or Action<ConvertedContext>, you’re working with context objects.
Why Context Objects?
Context objects provide:
Source information: File name, format, hierarchy level
Conversion state: Current page being processed, target format
Dynamic configuration: Configure options based on actual document properties
Lifecycle callbacks: Monitor conversion progress page-by-page or document-level
The Six Context Types
GroupDocs.Conversion provides six context types, each serving a specific purpose:
Used in: Converter constructor overloads with Func<LoadContext, LoadOptions> parameter
Purpose: Provides information about the source document when loading, enabling dynamic load options based on file properties.
Properties
Property
Type
Description
SourceFileName
string
Name of the source file (read-only)
SourceFormat
FileType
Format of the source document (read-only)
SourceStream
Stream
Source document stream (read-only)
HierarchyLevel
int
Nesting depth of current document in container hierarchy (read-only) *
ItemIndex
int
Absolute sequential counter across all items (read-only) *
* HierarchyLevel shows nesting depth (0 = root, 1 = embedded in root, etc.). ItemIndex is an absolute counter (1, 2, 3…) across all items regardless of hierarchy. For regular documents, these values are always 0 and 1.
Example
using(varconverter=newConverter("invoice-2024.pdf",(LoadContextloadContext)=>{// Access source informationConsole.WriteLine($"Loading file: {loadContext.SourceFileName}");Console.WriteLine($"Format: {loadContext.SourceFormat}");// Return appropriate load options based on formatreturnnewPdfLoadOptions();})){converter.Convert("invoice-2024.docx",newWordProcessingConvertOptions());}
ConvertContext
Used in: Convert() method overloads with Func<ConvertContext, ConvertOptions> parameter
Purpose: Provides conversion information and allows setting cancellation token for the conversion process.
Properties
Property
Type
Description
CancellationToken
CancellationToken
Cancellation token (get; set; - only settable property!)
SourceFileName
string
Name of the source file (read-only)
SourceFormat
FileType
Format of the source document (read-only)
Example
using(varconverter=newConverter("quarterly-report.pdf")){converter.Convert((ConvertContextconvertContext)=>{// Access conversion informationConsole.WriteLine($"Converting: {convertContext.SourceFileName}");Console.WriteLine($"From format: {convertContext.SourceFormat}");// Can set cancellation tokenconvertContext.CancellationToken=CancellationToken.None;returnnewWordProcessingConvertOptions();},(ConvertedContextconvertedContext)=>{// Save the converted stream to fileusing(varfileStream=File.Create("quarterly-report.docx")){convertedContext.ConvertedStream.CopyTo(fileStream);}});}
SaveContext
Used in: Convert() method overloads with Func<SaveContext, Stream> parameter
Purpose: Provides information about the conversion output, enabling custom stream handling for the converted document.
Properties
Property
Type
Description
SourceFileName
string
Name of the source file (read-only)
SourceFormat
FileType
Format of the source document (read-only)
TargetFormat
string
Target format for conversion (read-only)
HierarchyLevel
int
Nesting depth of current document in container hierarchy (read-only) *
ItemIndex
int
Absolute sequential counter across all items (read-only) *
* HierarchyLevel shows nesting depth (0 = root, 1 = embedded, etc.). ItemIndex is an absolute counter (1, 2, 3…) across all items. Only relevant for container documents (e.g., PST, OST, PDF with embedded files).
Used in: Convert() method overloads with Func<SavePageContext, Stream> parameter
Purpose: Provides page-specific information for page-by-page conversion, enabling custom stream handling for each converted page.
Properties
Property
Type
Description
Page
int
Page number from source document (read-only)
SourceFileName
string
Name of the source file (read-only)
SourceFormat
FileType
Format of the source document (read-only)
TargetFormat
string
Target format for conversion (read-only)
Example
using(varconverter=newConverter("contract-2024.pdf")){converter.Convert((SavePageContextsavePageContext)=>{// Access page-specific informationConsole.WriteLine($"Processing page: {savePageContext.Page}");Console.WriteLine($"Source: {savePageContext.SourceFileName}");Console.WriteLine($"From: {savePageContext.SourceFormat}");Console.WriteLine($"To: {savePageContext.TargetFormat}");// Return stream for this specific pagereturnFile.Create($"contract-2024-page-{savePageContext.Page}.png");},newImageConvertOptions());}
ConvertedContext
Used in: Convert() method overloads with Action<ConvertedContext> parameter
Purpose: Callback invoked after the entire document conversion completes, providing access to the converted stream and conversion details.
Properties
Property
Type
Description
ConvertedFormat
string
Format of the converted document (read-only)
ConvertedStream
Stream
Stream containing the converted document (read-only)
SourceFileName
string
Name of the source file (read-only)
SourceFormat
FileType
Format of the source document (read-only)
HierarchyLevel
int
Nesting depth of current document in container hierarchy (read-only) *
ItemIndex
int
Absolute sequential counter across all items (read-only) *
* HierarchyLevel shows nesting depth (0 = root, 1 = embedded, etc.). ItemIndex is an absolute counter (1, 2, 3…) across all items. Only relevant for container documents (e.g., PST, OST, PDF with embedded files).
Example
using(varconverter=newConverter("sales-report.pdf")){converter.Convert(newWordProcessingConvertOptions(),(ConvertedContextconvertedContext)=>{// Access conversion result informationConsole.WriteLine($"Converted: {convertedContext.SourceFileName}");Console.WriteLine($"From: {convertedContext.SourceFormat}");Console.WriteLine($"To: {convertedContext.ConvertedFormat}");Console.WriteLine("Conversion completed!");// Save the converted stream to fileusing(varfileStream=File.Create("sales-report.docx")){convertedContext.ConvertedStream.CopyTo(fileStream);}});}
ConvertedPageContext
Used in: Convert() method overloads with Action<ConvertedPageContext> parameter
Purpose: Callback invoked after each page conversion completes, enabling page-by-page monitoring and handling.
Properties
Property
Type
Description
ConvertedFormat
string
Format of the converted page (read-only)
ConvertedStream
Stream
Stream containing the converted page (read-only)
Page
int
Page number from source document (read-only)
SourceFileName
string
Name of the source file (read-only)
SourceFormat
FileType
Format of the source document (read-only)
Example
using(varconverter=newConverter("monthly-report.pdf")){converter.Convert(newWordProcessingConvertOptions(),(ConvertedPageContextconvertedPageContext)=>{// Access page conversion resultConsole.WriteLine($"Page {convertedPageContext.Page} converted");Console.WriteLine($"Format: {convertedPageContext.ConvertedFormat}");Console.WriteLine($"Source: {convertedPageContext.SourceFileName}");Console.WriteLine($"From: {convertedPageContext.SourceFormat}");// Save each page's stream to fileusing(varfileStream=File.Create($"monthly-report-page-{convertedPageContext.Page}.docx")){convertedPageContext.ConvertedStream.CopyTo(fileStream);}});}
Working with Container Documents
The HierarchyLevel and ItemIndex properties become relevant when converting container documents that can hold multiple items in a hierarchical structure.
Understanding HierarchyLevel and ItemIndex
HierarchyLevel: Shows the nesting depth of the current document
0 = Root/main document
1 = Directly embedded in main document
2 = Embedded within an embedded document, etc.
ItemIndex: Absolute sequential counter across ALL items
Starts at 1 and increments for each item
NOT per-hierarchy-level (it’s global)
Example hierarchy:
Main PDF (Level 0, Index 1)
├─ Attachment 1 (Level 1, Index 2)
├─ Attachment 2 (Level 1, Index 3)
└─ Attachment 3 (Level 1, Index 4)
└─ Sub-attachment (Level 2, Index 5)
Container Document Types
Email containers: PST, OST files (Outlook data files)
Email storage: MBOX, NSF, OLM files
PDF with attachments: PDF files containing embedded documents
Archive formats: ZIP files (when extracted and converted)
Example: Converting PST File with Hierarchy Information
using(varconverter=newConverter("mailbox-archive.pst")){intitemCount=0;converter.Convert((SaveContextsaveContext)=>{itemCount++;// Access hierarchy information for container itemsConsole.WriteLine($"Item #{itemCount}");Console.WriteLine($" Source: {saveContext.SourceFileName}");Console.WriteLine($" Hierarchy Level: {saveContext.HierarchyLevel}");Console.WriteLine($" Item Index: {saveContext.ItemIndex}");Console.WriteLine($" Target Format: {saveContext.TargetFormat}");// Create output file with hierarchy info in namevaroutputName=$"email-L{saveContext.HierarchyLevel}-I{saveContext.ItemIndex}.pdf";returnFile.Create(outputName);},newPdfConvertOptions());Console.WriteLine($"Total items converted: {itemCount}");}
Example: PDF with Embedded Files
// LoadContext is called for EACH document in the hierarchyusing(varconverter=newConverter("contract-with-attachments.pdf",(LoadContextloadContext)=>{// HierarchyLevel shows WHERE in the hierarchy this document is// Level 0 = main document// Level 1 = directly embedded in main document// Level 2 = embedded within an embedded document, etc.Console.WriteLine($"Loading: {loadContext.SourceFileName}");Console.WriteLine($" Hierarchy Level: {loadContext.HierarchyLevel}");Console.WriteLine($" Item Index: {loadContext.ItemIndex}");if(loadContext.HierarchyLevel==0){Console.WriteLine(" -> This is the main document");}elseif(loadContext.HierarchyLevel==1){Console.WriteLine(" -> This is an embedded file in the main document");}else{Console.WriteLine($" -> This is nested {loadContext.HierarchyLevel} levels deep");}// Return appropriate load options for the document typereturnnewPdfLoadOptions();})){intitemCount=0;converter.Convert((SaveContextsaveContext)=>{itemCount++;// SaveContext shows hierarchy level during conversionvaroutputName=$"contract-L{saveContext.HierarchyLevel}-I{saveContext.ItemIndex}.pdf";Console.WriteLine($"Saving: {outputName}");returnFile.Create(outputName);},newPdfConvertOptions());Console.WriteLine($"Total items converted: {itemCount}");}
Key Points:
LoadContext is called once for each document in the container hierarchy (main document + each embedded document)
HierarchyLevel shows the nesting depth of the document currently being loaded/converted:
HierarchyLevel = 0 → Main/root document
HierarchyLevel = 1 → Directly embedded in main document
HierarchyLevel = 2 → Embedded within an embedded document, etc.
ItemIndex is an absolute sequential counter - counts all items across the entire conversion (1, 2, 3, 4…), regardless of hierarchy level
For regular documents (DOCX, XLSX, simple PDF without embedded files), HierarchyLevel is always 0 and ItemIndex is always 1
Common Patterns
Pattern 1: Dynamic Load Options Based on Source
using(varconverter=newConverter("annual-report.pdf",(LoadContextloadContext)=>{// Choose load options based on actual file formatif(loadContext.SourceFormat==FileType.Pdf)returnnewPdfLoadOptions{RemoveEmbeddedFiles=true};if(loadContext.SourceFormat==FileType.Docx)returnnewWordProcessingLoadOptions{DefaultFont="Arial"};returnnull;// Auto-detect})){converter.Convert("annual-report.xlsx",newSpreadsheetConvertOptions());}
Pattern 2: Page-by-Page Conversion with Custom Names
using(varconverter=newConverter("employee-handbook.pdf")){converter.Convert((SavePageContextsavePageContext)=>{// Create separate file for each page with custom namingvarfileName=$"handbook-section-{savePageContext.Page:D3}.docx";returnFile.Create(fileName);},newWordProcessingConvertOptions());}
Pattern 3: Conversion Progress Monitoring
intprocessedPages=0;using(varconverter=newConverter("product-catalog.pdf")){converter.Convert(newImageConvertOptions{Format=ImageFileType.Png},(ConvertedPageContextconvertedPageContext)=>{processedPages++;Console.WriteLine($"Progress: Page {processedPages} of product catalog converted");// Save page streamusing(varfileStream=File.Create($"catalog-page-{convertedPageContext.Page:D3}.png")){convertedPageContext.ConvertedStream.CopyTo(fileStream);}});}
Migration from Pre-v24.10 API
Before v24.10
// Old API used primitive parametersusing(varconverter=newConverter("financial-statement.docx")){converter.Convert((intpage)=>File.Create($"statement-page-{page}.pdf"),newPdfConvertOptions());}
v24.10 and Later
// New API uses SavePageContext with rich context informationusing(varconverter=newConverter("financial-statement.docx")){converter.Convert((SavePageContextsavePageContext)=>{// Access rich context informationConsole.WriteLine($"Converting page {savePageContext.Page} of {savePageContext.SourceFileName}");returnFile.Create($"statement-page-{savePageContext.Page}.pdf");},newPdfConvertOptions());}
Summary
Context objects are foundational to GroupDocs.Conversion’s delegate-based patterns. Understanding them enables you to:
LoadContext: Configure dynamic load options based on source properties
ConvertContext: Control conversion process and access source information
SaveContext: Handle custom output streams with full target information
SavePageContext: Process pages individually with page-specific context