Use basic PDF objects for currently unsupported PDF features in C# and VB.NET

With GemBox.Pdf, you can use basic PDF objects for currently unsupported PDF features in your C# or VB.NET application.

For more information about basic PDF objects, see Objects help page.

The following example demonstrates how a page-piece dictionary can be used to hold private application data.

Screenshot
PDF Library for C# / VB.NET Screenshot

See the full code below, use Run Example to execute.

Upload your file(Drag files here)

Download an input file

using System;
using System.Globalization;
using System.Text;
using GemBox.Pdf;
using GemBox.Pdf.Filters;
using GemBox.Pdf.Objects;
using GemBox.Pdf.Text;

class Sample
{
    [STAThread]
    static void Main(string[] args)
    {
        // If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        PdfDocument document = PdfDocument.Load("LoremIpsum.pdf");

        // Get document's trailer dictionary.
        var trailer = document.GetDictionary();
        // Get document catalog dictionary from the trailer.
        var catalog = (PdfDictionary)((PdfIndirectObject)trailer[PdfName.Create("Root")]).Value;

        // Either retrieve "PieceInfo" entry value from document catalog or create a page-piece dictionary and set it to document catalog under "PieceInfo" entry.
        PdfDictionary pieceInfo;
        var pieceInfoKey = PdfName.Create("PieceInfo");
        var pieceInfoValue = catalog[pieceInfoKey];
        switch (pieceInfoValue.ObjectType)
        {
            case PdfBasicObjectType.Dictionary:
                pieceInfo = (PdfDictionary)pieceInfoValue;
                break;
            case PdfBasicObjectType.IndirectObject:
                pieceInfo = (PdfDictionary)((PdfIndirectObject)pieceInfoValue).Value;
                break;
            case PdfBasicObjectType.Null:
                pieceInfo = PdfDictionary.Create();
                catalog[pieceInfoKey] = PdfIndirectObject.Create(pieceInfo);
                break;
            default:
                throw new InvalidOperationException("PieceInfo entry must be dictionary.");
        }

        // Create page-piece data dictionary for "GemBox.Pdf" conforming product and set it to page-piece dictionary.
        var data = PdfDictionary.Create();
        pieceInfo[PdfName.Create("GemBox.Pdf")] = data;

        // Create a private data dictionary that will hold private data that "GemBox.Pdf" conforming product understands.
        var privateData = PdfDictionary.Create();
        data[PdfName.Create("Data")] = privateData;

        // Set "Title" and "Version" entries to private data.
        privateData[PdfName.Create("Title")] = PdfString.Create(ComponentInfo.Title);
        privateData[PdfName.Create("Version")] = PdfString.Create(ComponentInfo.Version);

        // Specify date of the last modification of "GemBox.Pdf" private data (required by PDF specification).
        data[PdfName.Create("LastModified")] = PdfString.Create("D:" + DateTimeOffset.Now.ToString("yyyyMMddHHmmssK", CultureInfo.InvariantCulture).Replace(':', '\'') + "'", PdfEncoding.ASCII, PdfStringForm.Literal);

        document.Save("Basic Objects.pdf");
        document.Close();
    }
}
Imports System.Globalization
Imports System.IO
Imports System.Text
Imports GemBox.Pdf
Imports GemBox.Pdf.Filters
Imports GemBox.Pdf.Objects
Imports GemBox.Pdf.Text

Module Samples

    Sub Main()

        ' If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        Dim document As PdfDocument = PdfDocument.Load("LoremIpsum.pdf")

        ' Get document's trailer dictionary.
        Dim trailer = document.GetDictionary()
        ' Get document catalog dictionary from the trailer.
        Dim catalog = CType((CType(trailer(PdfName.Create("Root")), PdfIndirectObject)).Value, PdfDictionary)

        ' Either retrieve "PieceInfo" entry value from document catalog or create a page-piece dictionary and set it to document catalog under "PieceInfo" entry.
        Dim pieceInfo As PdfDictionary
        Dim pieceInfoKey = PdfName.Create("PieceInfo")
        Dim pieceInfoValue = catalog(pieceInfoKey)
        Select Case pieceInfoValue.ObjectType
            Case PdfBasicObjectType.Dictionary
                pieceInfo = CType(pieceInfoValue, PdfDictionary)
            Case PdfBasicObjectType.IndirectObject
                pieceInfo = CType((CType(pieceInfoValue, PdfIndirectObject)).Value, PdfDictionary)
            Case PdfBasicObjectType.Null
                pieceInfo = PdfDictionary.Create()
                catalog(pieceInfoKey) = PdfIndirectObject.Create(pieceInfo)
            Case Else
                Throw New InvalidOperationException("PieceInfo entry must be dictionary.")
        End Select

        ' Create page-piece data dictionary for "GemBox.Pdf" conforming product and set it to page-piece dictionary.
        Dim data = PdfDictionary.Create()
        pieceInfo(PdfName.Create("GemBox.Pdf")) = data

        ' Create a private data dictionary that will hold private data that "GemBox.Pdf" conforming product understands.
        Dim privateData = PdfDictionary.Create()
        data(PdfName.Create("Data")) = privateData

        ' Set "Title" and "Version" entries to private data.
        privateData(PdfName.Create("Title")) = PdfString.Create(ComponentInfo.Title)
        privateData(PdfName.Create("Version")) = PdfString.Create(ComponentInfo.Version)

        ' Specify date of the last modification of "GemBox.Pdf" private data (required by PDF specification).
        data(PdfName.Create("LastModified")) = PdfString.Create("D:" & DateTimeOffset.Now.ToString("yyyyMMddHHmmssK", CultureInfo.InvariantCulture).Replace(":"c, "'"c) & "'", PdfEncoding.ASCII, PdfStringForm.Literal)

        document.Save("Basic Objects.pdf")
        document.Close()

    End Sub

End Module