Free Support Forum -

Is there a way to programmatically generate an annotated PDF?

We have various scenarios where we need to generate the annotated PDF programmatically so it can be downloaded later from another screen. This screen does not have the Groupdocs interface.

The file exporter calls document-annotation/ExportAnnotations. However, this method requires the Signalr connection ID. Is there another way to export the annotations without the Signalr connection ID?



Hello Jason,

Thank you for interesting question. Yes, this is possible, and I’ll show you how. Let’s suppose that you have ASP.NET WebForms application. Annotation server control (widget) is placed on the defined page. You visit this page, add some annotation, save them, but do not make a export or saving. And for another page you want to generate document with annotations inserted inside and download this file to the client. Here is how to do this.

ASPX page (code-front)
<%@ Page Language=“C#” AutoEventWireup=“true” CodeBehind=“DownloadAnnotated.aspx.cs” Inherits=“Groupdocs.Demo.Annotation.Webforms.DownloadAnnotated” %>

Downloading page

<asp:Button runat=“server” ID=“btnDownloadAnnotated” Text=“Download Annotated doc” OnClick=“btnDownloadAnnotated_Click”/>

ASPX.cs page (code-behind)
using System;
using System.Globalization;
using System.IO;
using Groupdocs.Common;
using Groupdocs.Web.Annotation;
using Groupdocs.Web.Annotation.Utils;

namespace Groupdocs.Demo.Annotation.Webforms
public partial class DownloadAnnotated : System.Web.UI.Page
private const string _filePath = “Quick_Start_Guide_To_Using_GroupDocs.pdf”;

private const string _groupdocsTemp = “Saaspose”;

protected void Page_Load(object sender, EventArgs e)


protected void btnDownloadAnnotated_Click(object sender, EventArgs e)
long sessionId = FileSessionMapper.Instance[_filePath];
string tempFileName = AnnotationsExporter.Perform(sessionId, _filePath, DocumentType.Pdf, AnnotationMode.TrackChanges);
string tempFilePath = Path.Combine(Path.GetTempPath(), _groupdocsTemp, tempFileName);

this.Response.ContentType = “application/” + DocumentType.Pdf.ToString();
this.Response.AppendHeader(“Content-Disposition”, “attachment; filename=”" + tempFileName+""");
this.Response.AppendHeader(“Content-Length”, new FileInfo(tempFilePath).Length.ToString(CultureInfo.InvariantCulture));

If you will have more questions please feel free to contact us.


Thank you Denis.

I have this working now.