Products Technologies Demo Docs Blog Support Company

How to Add Electronic and Digital Signatures to PDFs in ASP.NET Core C# and Angular

Learn how to add electronic and digital signatures to PDFs in ASP.NET Core C# and Angular. This tutorial shows how to create an Angular application with an ASP.NET Core backend that uses the Document Viewer to display and sign PDF documents.

How to Add Electronic and Digital Signatures to PDFs in ASP.NET Core C# and Angular

In this article, you will learn how to sign a document and export it as a PDF using Angular and an ASP.NET Core backend. Using TX Text Control .NET Server and the Document Viewer for Angular, the electronic signature is captured and applied to a signature field that is digitally signed with a certificate to ensure that your documents are secure and reliable.

TX Text Control provides all the necessary capabilities to capture signatures from end users and process the document to create a fully signed and secure PDF document. It provides the server-side API to generate the PDF and the front-end UI tools for a modern, reliable and effortless signature experience.

Signature Support

TX Text Control provides two different types of signatures: Electronic signatures and digital signatures.

  • Electronic Signature
    An electronic signature is a signature that is captured using a touch screen or a mouse. It is a visual representation of a signature that is placed on a document. It is not necessarily cryptographically secured, but can be digitally signed.
  • Digital Signature
    A digital signature is a cryptographic signature that is applied to a document. It is cryptographically secured and ensures that the document has not been tampered with. It is based on a certificate that is issued by a trusted authority.

In most typical scenarios, the two types are combined so that visual signature fields contain the visual representation and are digitally signed with a certificate.

Document Viewer for Angular

The Document Viewer for Angular is a modern, web-based document viewer that is available for many platforms and provides all the functionality needed to capture signatures.

  • Out-of-the-box UI
    The Document Viewer for Angular provides a ready-to-use UI to display and sign documents. It is customizable and can be integrated into any Angular application.

    Angular Document Viewer UI

  • Signature Fields
    The Document Viewer for Angular provides support for signature fields that can be placed on the document to capture electronic signatures. These fields can be digitally signed with a certificate to ensure that the document is secure and reliable.

    Angular Document Viewer Signature Fields

  • Form Filling
    The Document Viewer for Angular provides support for form fields that can be placed on the document to capture data. These fields can be exported as a PDF form.

    Angular Document Viewer Forms Filling

  • Draw, Type or Upload Signatures
    The Document Viewer for Angular provides different ways to capture signatures. Users can draw, type or upload a signature image to sign the document.

    Angular Document Viewer Signature Capture

Prerequisites

In order to get started, you will need the following components:

npm and Angular command-line interface (CLI)

The client-side part of this tutorial can also be built independently of Visual Studio using the Angular CLI. To learn how to create an Angular CLI application using the TX Text Control, read this article.

Getting Started: Document Editor with Angular CLI v17.0

Creating the Application

The following tutorial will show you how to create an Angular with ASP.NET Core application that includes the client-side npm package and the required backend middleware.

  1. In Visual Studio 2022, create a new project, select Angular with ASP.NET Core as the project template and continue with Next.

    ASP.NET Core with Angular application

  2. Select a project name and location confirm with Next.

  3. Choose .NET 8 (Long Term Support) as the Framework, enable Use Controllers and continue with Create.

    ASP.NET Core with Angular application

Adding NuGet Packages

  1. Right-click on the project that ends with .Server in the Solution Explorer and select Manage NuGet Packages....

    Select Text Control Offline Packages from the Package source drop-down.

    Install the latest versions of the following packages:

    • TXTextControl.TextControl.ASP.SDK
    • TXTextControl.Web.DocumentViewer

    NuGet Packages

  2. Switch the package source to nuget.org and choose Installed to check for available updates. Update the installed packages to the most current version.

Preparing the Pipeline

  1. Open the file Program.cs in the .Server project and a replace the complete code with the following code:

    using TXTextControl.Web.MVC.DocumentViewer;
    var builder = WebApplication.CreateBuilder(args);
    
    // adding CORS policy to allow all origins
    builder.Services.AddCors(options =>
    {
      options.AddDefaultPolicy(
             builder =>
             {
               builder.AllowAnyOrigin()
                  .AllowAnyMethod()
                  .AllowAnyHeader();
             });
    });
    
    // Add services to the container.
    builder.Services.AddControllers();
    
    var app = builder.Build();
    app.UseDefaultFiles();
    app.UseStaticFiles();
    
    // Configure the HTTP request pipeline.
    app.UseHttpsRedirection();
    app.UseAuthorization();
    app.UseRouting();
    
    // adding CORS middleware
    app.UseCors();
    
    app.UseTXDocumentViewer();
    app.MapControllers();
    app.MapFallbackToFile("/index.html");
    app.Run();

Adding npm Packages

The Angular application has already been created by the Visual Studio project template and is available in the Solution Explorer ending with .client.

  1. In the Solution Explorer, expand the Angular application node, right-click npm, and select Install new npm packages from the context menu.

    Install new npm packages

  2. Search for @txtextcontrol/tx-ng-document-viewer and install the package. Add --legacy-peer-deps as a Other npm arguments to force the installation for newer Angular versions.

    Install @txtextcontrol/tx-ng-document-viewer

  3. Open the file src -> app -> app.module.ts, add replace the complete content with the following code and save it:

    import { HttpClientModule } from '@angular/common/http';
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    import { DocumentViewerModule } from '@txtextcontrol/tx-ng-document-viewer';
    
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule, HttpClientModule,
        AppRoutingModule, DocumentViewerModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

Creating the Self-Signed Certificate

In the next steps, a self-signed certificate is created using Windows PowerShell.

  • Use the New-SelfSignedCertificate PowerShell cmdlet to create a self signed certificate. Open a PowerShell and type in the following command:

    New-SelfSignedCertificate -Type Custom -Subject "CN=Text Control, O=Text Control, C=US" -KeyUsage DigitalSignature -FriendlyName "TextControlSelf" -CertStoreLocation "Cert:\CurrentUser\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")

    After running this command, the certificate is added to the certificate store (specified in the "-CertStoreLocation" parameter). The output of the command shows the certificate's thumbprint.

    PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\My
    
    Thumbprint                                Subject
    ----------                                -------
    6BA35B742656FB2EC48B09116ABAE5123082F116  CN=Text Control, O=Text Control, C=US
  • Copy this thumbprint and insert it into the following command:

    $password = ConvertTo-SecureString -String yourpassword -Force -AsPlainText 
    Export-PfxCertificate -cert "Cert:\CurrentUser\My\6BA35B742656FB2EC48B09116ABAE5123082F116" -FilePath textcontrolself.pfx -Password $password
  • The file textcontrol_self.pfx is created in the same folder. Copy this to your application's folder from where you want to load the certificate (App_Data in our Web API sample above).

Creating the Controller

  1. Right-click on the Controllers folder in the .Server project and select Add -> Controller.... Choose MVC Controller - Empty and confirm with Add. Name it DocumentController and click Add.

  2. Replace the complete content of the DocumentController.cs with the following code:

    using Microsoft.AspNetCore.Mvc;
    using System.Security.Cryptography.X509Certificates;
    using TXTextControl;
    using TXTextControl.Web.MVC.DocumentViewer;
    using TXTextControl.Web.MVC.DocumentViewer.Models;
    
    namespace MyAngularBackend.Server.Controllers
    {
      [ApiController]
      [Route("[controller]")]
      public class DocumentController : ControllerBase
      {
    
        private readonly ILogger<DocumentController> _logger;
    
        public DocumentController(ILogger<DocumentController> logger)
        {
          _logger = logger;
        }
    
        [HttpGet]
        [Route("Load")]
        public DocumentData Load()
        {
          // open file as byte and convert to base64
          byte[] fileBytes = System.IO.File.ReadAllBytes("App_Data/document.tx");
          string file = Convert.ToBase64String(fileBytes);
          return new DocumentData { Name = "document.pdf", Document = file };
        }
    
        [HttpPost]
        [Route("Sign")]
        public string Sign([FromBody] SignatureData signatureData)
        {
          byte[] bPDF;
    
          // create temporary ServerTextControl
          using (ServerTextControl tx = new ServerTextControl())
          {
            tx.Create();
    
            // load the document
            tx.Load(Convert.FromBase64String(signatureData.SignedDocument.Document),
              BinaryStreamType.InternalUnicodeFormat);
    
            // create a certificate
            X509Certificate2 cert = new X509Certificate2("App_Data/textcontrol_self.pfx", "123");
    
            // create a list of digital signatures
            var signatureFields = new List<DigitalSignature>();
    
            // create a digital signature for each signature box
            foreach (SignatureBox box in signatureData.SignatureBoxes)
            {
              signatureFields.Add(new DigitalSignature(cert, null, box.Name));
            }
    
            // create save settings
            SaveSettings saveSettings = new SaveSettings()
            {
              CreatorApplication = "Your Application",
              SignatureFields = signatureFields.ToArray()
            };
    
            // save the document as PDF
            tx.Save(out bPDF, BinaryStreamType.AdobePDFA, saveSettings);
          }
    
          // return as Base64 encoded string
          return Convert.ToBase64String(bPDF);
        }
      }
    }

Adding the Document Viewer

  1. Open the file src -> app -> app.component.ts and replace the complete content with the following code:

    import { HttpClient } from '@angular/common/http';
    import { Component, OnInit, HostListener } from '@angular/core';
    
    declare const TXDocumentViewer: any;
    interface DocumentData {
      document?: string;
      name?: string;
    }
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrl: './app.component.css',
    })
    export class AppComponent implements OnInit {
    
      public documentData: DocumentData = {};
    
      constructor(private http: HttpClient) { }
    
      @HostListener('window:documentViewerLoaded', ['$event'])
      onDocumentViewerLoaded() {
    
        TXDocumentViewer.signatures.setSubmitCallback(function (data: string) {
          var element = document.createElement('a');
          element.setAttribute('href', 'data:application/pdf;;base64,' + data);
          element.setAttribute('download', "results.pdf");
          document.body.appendChild(element);
          element.click();
        })
    
        var signatureSettings = {
          showSignatureBar: true,
          redirectUrlAfterSignature: 'https://localhost:7275/document/sign',
          ownerName: 'Paul',
          signerName: 'Jacob',
          signerInitials: 'PK',
          signatureBoxes: [{ name: 'txsign', signingRequired: true, style: 0 }]
        };
    
        TXDocumentViewer.loadDocument(this.documentData.document, this.documentData.name, signatureSettings);
      }
    
      ngOnInit() {
        this.getDocument();
      }
    
      getDocument() {
        this.http.get<DocumentData>('/document/load').subscribe(
          (result) => {
            this.documentData = result;
          }
        );
      }
    
      title = 'myangularbackend.client';
    }
  2. Open the file src -> app -> app.component.html and replace the complete content with the following code:

    <tx-document-viewer width="800px"
                        height="800px"
                        basePath="https://localhost:7275"
                        dock="Window"
                        [toolbarDocked]="true"
                        [showThumbnailPane]="true">
    </tx-document-viewer>

    The port number in the code (in this case 7275) can be found in the Properties -> launchSettings.json file of your .Server application.

  3. Open the file src -> proxy.conf.js and replace the code with the following code:

    const PROXY_CONFIG = [
      {
        context: [
          "/document",
        ],
        target: "https://localhost:7275",
        secure: false
      }
    ]
    
    module.exports = PROXY_CONFIG;

    Replace the port number with the appropriate port number, similar to the previous step.

Adding a Sample Document

  1. Download the sample document document.tx and save it to the App_Data folder of the .Server project. Create the folder, if it doesn't exist.

Running the Application

  1. Run the application by pressing F5 in Visual Studio. The application starts and the Document Viewer is loaded with the sample document.

    Running the application

  2. Click on the signature field to sign the document. The signature dialog is opened and the signature can be drawn, typed or uploaded.

  3. After signing the document, the signature is applied and the document is digitally signed with the certificate.

    Signed document

Workflow Explanation

The following is a step-by-step description of the signing process.

Loading the Document

When the application is started, the document is loaded from the server and displayed in the Document Viewer. This is done using an HttpGet method that retrieves the template from the server.

getDocument() {
 this.http.get<DocumentData>('/document/load').subscribe(
   (result) => {
     this.documentData = result;
   }
 );
}

Server-side, the Load method returns the document to be loaded and returned as a base64-encoded string.

[HttpGet]
[Route("Load")]
public DocumentData Load()
{
  // open file as byte and convert to base64
  byte[] fileBytes = System.IO.File.ReadAllBytes("App_Data/document.tx");
  string file = Convert.ToBase64String(fileBytes);
  return new DocumentData { Name = "document.pdf", Document = file };
}

Signing the Document

When all signature fields are signed, the Sign method is called. The implemented HttpPost endpoint Sign is requested by the Document Viewer after the signing process. In this method, a digital certificate is applied to the signed electronic signature representation using the SignatureFields property. This property specifies an array of DigitalSignature objects, each of which defines an X.509 certificate and is associated with a SignatureField in the document. These certificates can be used to digitally sign a PDF or a PDF/A file.

[HttpPost]
[Route("Sign")]
public string Sign([FromBody] SignatureData signatureData)
{
  byte[] bPDF;

  // create temporary ServerTextControl
  using (ServerTextControl tx = new ServerTextControl())
  {
    tx.Create();

    // load the document
    tx.Load(Convert.FromBase64String(signatureData.SignedDocument.Document),
      BinaryStreamType.InternalUnicodeFormat);

    // create a certificate
    X509Certificate2 cert = new X509Certificate2("App_Data/textcontrol_self.pfx", "123");

    // create a list of digital signatures
    var signatureFields = new List<DigitalSignature>();

    // create a digital signature for each signature box
    foreach (SignatureBox box in signatureData.SignatureBoxes)
    {
      signatureFields.Add(new DigitalSignature(cert, null, box.Name));
    }

    // create save settings
    SaveSettings saveSettings = new SaveSettings()
    {
      CreatorApplication = "Your Application",
      SignatureFields = signatureFields.ToArray()
    };

    // save the document as PDF
    tx.Save(out bPDF, BinaryStreamType.AdobePDFA, saveSettings);
  }

  // return as Base64 encoded string
  return Convert.ToBase64String(bPDF);
}

The following diagram illustrates the signature workflow.

Signature Workflow

Conclusion

This tutorial showed how to create an Angular application with an ASP.NET Core backend that uses the Document Viewer to display and sign PDF documents. The Document Viewer provides all the necessary UI and API to capture signatures and to digitally sign the document with a certificate. The server-side API provides the necessary methods to load and save the document and to apply the digital signature.

Download the sample from GitHub and test the signature process with your own certificate.

Stay in the loop!

Subscribe to the newsletter to receive the latest updates.

GitHub

Download and Fork This Sample on GitHub

We proudly host our sample code on github.com/TextControl.

Please fork and contribute.

Download ZIP

Open on GitHub

Open in Visual Studio

Requirements for this sample

  • TX Text Control .NET Server Core
  • Visual Studio 2022

Angular

Integrate document processing, editing, sharing, collaboration, creation, electronic signatures, and PDF generation into your Angular Web applications.

Learn more about Angular

Related Posts

ASP.NETASP.NET CoreE-Sign

Adoption of Electronic vs. Paper Signatures in 2025

The move to electronic signatures has accelerated in recent years. However, many organizations still rely on paper signatures for core processes. This article examines the current state of…


AngularASP.NETBlazor

Building an ASP.NET Core Backend (Linux and Windows) for the Document Editor…

This article shows how to create a backend for the Document Editor and Viewer using ASP.NET Core. The backend can be hosted on Windows and Linux and can be used in Blazor, Angular, JavaScript, and…


ASP.NETASP.NET CoreDocument Editor

Preparing Documents for E-Signing for Multiple Signers in .NET C#

Learn how to prepare documents for e-signing by multiple signers in .NET C#. This article shows how to create signature fields and how to assign them to signers.


ASP.NETASP.NET CoreDocument Viewer

Optimizing Digital Signature Workflows: Starting with MS Word DOCX Files…

Starting a digital signature workflow with MS Word DOCX files instead of PDFs provides greater flexibility, ease of editing, and collaboration during the document preparation phase. DOCX files are…


AngularASP.NET CoreDocument Viewer

Getting Started Video Tutorial: How to use the Document Viewer in Angular

This video tutorial shows how to use the Document Viewer in an Angular application. This tutorial is part of the TX Text Control Getting Started series originally published on our YouTube channel.