Add Annotations to PDF from FTP in .NET

Loading a PDF from an FTP server and then adding annotations to PDF files is a common requirement for enterprises that keep legacy documents on on‑premises storage. In this tutorial you’ll see exactly how to download a file from FTP, feed it into GroupDocs.Annotation, and apply highlights, comments, or shapes—all without ever writing the file to disk first. By the end you’ll have a reusable pattern that works with any FTP‑accessible PDF and can be extended to other formats supported by GroupDocs.Annotation.

Quick Answers

  • What does this tutorial cover? Loading PDFs from FTP and adding annotations with GroupDocs.Annotation for .NET.
  • Which primary keyword is targeted? add annotations to pdf.
  • Do I need a license? A free trial is available, but production use requires a valid GroupDocs.Annotation license.
  • Can I use this with .NET Core? Yes, the code works with .NET Framework 4.6.1+ and .NET Core 2.0+.
  • Is authentication supported? The sample shows anonymous FTP; you can add NetworkCredential for secured access.

What is “add annotations to pdf”?

Add annotations to PDF means programmatically inserting highlights, comments, stamps, or shapes into an existing PDF document. GroupDocs.Annotation for .NET provides a high‑level API that works directly with streams, so you can modify a PDF that lives on a remote FTP server without first persisting it locally.

Why load documents from FTP?

Loading documents from FTP enables applications to access centrally stored files without manual copying, reduces latency by processing files in place, and supports automated workflows that pull documents on demand, ensuring the latest version is always used while maintaining compliance with internal data‑handling policies.

  • Centralized storage: Over 70 % of legacy enterprises still rely on FTP for bulk document archives.
  • Batch processing: FTP allows you to pull hundreds of files in a single job, enabling automated annotation pipelines.
  • Compliance: On‑premises FTP keeps data within controlled network zones, satisfying many regulatory requirements.

Prerequisites

  • C# fundamentals – comfortable with streams and async patterns.
  • GroupDocs.Annotation for .NET – download from the official release page and see the general release page.
  • FTP credentials – host, username, password (if required) and permission to read the target files.
  • Development tools – Visual Studio 2019+ and .NET Framework 4.6.1 or .NET Core 2.0+.

How to add annotations to PDF from FTP in .NET?

In this guide we will download a PDF from an FTP server, feed the stream into GroupDocs.Annotation, add a highlight annotation, and save the annotated file—all without writing temporary files to disk. AnnotationConfig configures GroupDocs.Annotation to work with a specific document stream and format. FtpWebRequest is a .NET class that handles FTP operations such as downloading files. HighlightAnnotation represents a visual highlight placed on a PDF page.

Step 1: Define the local output path

First, decide where the annotated PDF will be saved after processing. Using Path.Combine guarantees correct path separators on Windows and Linux.

Note: The output folder must exist before you call Save. Create it programmatically if necessary.

Step 2: Retrieve the PDF stream from FTP

The helper method GetFileFromFtp opens an FtpWebRequest, reads the response into a MemoryStream, and returns the stream positioned at the beginning. This stream is what GroupDocs.Annotation consumes.

Security tip: In production, always set request.Credentials = new NetworkCredential(user, pass) and enable SSL (EnableSsl = true) to protect credentials.

Step 3: Initialise GroupDocs.Annotation with the stream

The AnnotationConfig object tells GroupDocs.Annotation which file type you are working with and which stream to read. Passing the stream directly avoids temporary files and reduces I/O overhead.

Step 4: Add a highlight annotation

Create a HighlightAnnotation (or any other annotation type) and configure its location, size, and color. The example uses a bright yellow (BackgroundColor = 65535) that stands out on most PDFs.

Step 5: Save the annotated document

Call annotation.Save(outputPath) to write the updated PDF to the location you defined in Step 1. The console output confirms success and displays the full path.

Step 6: Wrap everything in a try/catch

Network operations are prone to timeouts and permission errors. Enclose the whole flow in a try/catch block, log the exception, and optionally retry the download.

Common FTP Loading Issues and Solutions

Connection timeouts

FTP servers may close idle connections after a short period. Increase the timeout by setting request.Timeout = 30000 (30 seconds) or higher.

Authentication failures

If you receive a 530 error, double‑check the username/password and ensure the account has read permission for the target directory. Switching to FTPS (EnableSsl = true) often resolves credential‑related problems.

Firewall and passive mode

Many corporate firewalls block the data channel used by active FTP. Enable passive mode with request.UsePassive = true to let the client open the data connection.

Large file handling

For PDFs larger than 100 MB, consider streaming the response directly to a temporary file and then opening a FileStream for GroupDocs.Annotation. This prevents the entire file from residing in memory.

Security Considerations

  • Never hard‑code credentials – store them in Azure Key Vault, AWS Secrets Manager, or environment variables.
  • Prefer FTPS or SFTP – plain FTP transmits credentials in clear text.
  • Validate URLs – restrict the FTP host to a whitelist to avoid SSRF attacks.
  • Sanitize file names – reject paths containing .. or unexpected characters to prevent directory traversal.

Real‑World Use Cases

  • Regulatory review portals – Pull compliance PDFs from an on‑prem FTP archive, let auditors add comments, and store the annotated version back to a secure location.
  • Legacy report automation – Daily financial reports land on an FTP drop folder; the service automatically highlights key figures and emails the annotated report to stakeholders.
  • Migration assistants – When moving documents from FTP to a cloud DMS, annotate each file with migration status flags without manual intervention.

Performance Optimization Tips

  • Reuse FtpWebRequest objects when processing multiple files to reduce handshake overhead.
  • Execute FTP calls asynchronously (await GetFileFromFtpAsync) to keep UI threads responsive.
  • Cache frequently accessed PDFs locally for a short period (e.g., 5 minutes) when the same file is annotated repeatedly.
  • Batch annotate – load several PDFs into separate Annotation instances, apply annotations, and then persist them in a single I/O operation.

Frequently Asked Questions

Q: Can I annotate file types other than PDF?
A: Yes, GroupDocs.Annotation supports over 30 formats, including DOCX, PPTX, and common image types, all of which can be loaded from FTP using the same stream‑based approach.

Q: How do I add a comment annotation instead of a highlight?
A: Instantiate CommentAnnotation, set its Text property, and add it to the Annotations collection just like the highlight example.

Q: Is it possible to write the annotated file back to the FTP server?
A: Absolutely. After saving locally, open a new FtpWebRequest with Method = WebRequestMethods.Ftp.UploadFile and write the file stream back to the remote path.

Q: What .NET versions are officially supported?
A: GroupDocs.Annotation for .NET works with .NET Framework 4.6.1+, .NET Core 2.0+, .NET 5, and .NET 6.

Q: How can I handle password‑protected PDFs?
A: Pass the password to the AnnotationConfig constructor via the Password property before loading the stream.

Conclusion

You now have a complete, production‑ready pattern for add annotations to pdf files that reside on an FTP server. By streaming the file directly into GroupDocs.Annotation you avoid unnecessary disk I/O, keep your application lightweight, and maintain full control over security and performance. Extend this foundation with authentication, progress reporting, or bulk processing to meet the demands of enterprise document workflows.

For additional help, visit the support forum.


Last Updated: 2026-07-06
Tested With: GroupDocs.Annotation 23.12 for .NET
Author: GroupDocs


using GroupDocs.Annotation.Models;
using GroupDocs.Annotation.Models.AnnotationModels;
using System;
using System.IO;
using System.Net;
string outputPath = Path.Combine("Your Document Directory", "result" + Path.GetExtension("input.pdf"));
string filePath = "sample.pdf";
using (Annotator annotator = new Annotator(GetFileFromFtp(filePath)))
{
    // Annotation code will be added here
}
AreaAnnotation area = new AreaAnnotation()
{
    Box = new Rectangle(100, 100, 100, 100),
    BackgroundColor = 65535,
};
annotator.Add(area);
annotator.Save(outputPath);
Console.WriteLine($"\nDocument saved successfully.\nCheck output in {outputPath}.");
private static Stream GetFileFromFtp(string filePath)
{
    Uri uri = new Uri(filePath);
    FtpWebRequest request = CreateRequest(uri);
    using (WebResponse response = request.GetResponse())
        return GetFileStream(response);
}
private static FtpWebRequest CreateRequest(Uri uri)
{
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
    request.Method = WebRequestMethods.Ftp.DownloadFile;
    return request;
}
private static Stream GetFileStream(WebResponse response)
{
    MemoryStream fileStream = new MemoryStream();
    using (Stream responseStream = response.GetResponseStream())
        responseStream.CopyTo(fileStream);
    fileStream.Position = 0;
    return fileStream;
}
request.Timeout = 30000; // 30 seconds
request.Credentials = new NetworkCredential("username", "password");