Skip to content

Migration Guide v5

ATimmeh33 edited this page Feb 6, 2026 · 1 revision

Signhost API Client v5 Migration Guide

This document provides a comprehensive guide for migrating from Signhost API Client v4.x to v5.0. This is a major version upgrade with significant breaking changes.


Table of Contents

  1. Target Framework Changes
  2. JSON Serialization Changes (Newtonsoft.Json → System.Text.Json)
  3. Interface & Class Naming Changes
  4. API Method Signature Changes
  5. Data Object Changes
  6. Verification System Refactoring
  7. Exception Handling Changes
  8. File Digest Changes
  9. Removed Types and Members
  10. Nullable Reference Types
  11. Other Breaking Changes

Target Framework Changes

BREAKING: Target Framework Updates

Before (v4):

  • netstandard2.0
  • netstandard1.4
  • net462

After (v5):

  • net10.0
  • net9.0
  • net8.0
  • netstandard2.0
  • net462

Migration:

  • netstandard1.4 has been removed - Upgrade to netstandard2.0 or a specific .NET version.
  • If you were targeting netstandard1.4, you must update your project to target at least netstandard2.0.

JSON Serialization Changes

BREAKING: Newtonsoft.Json → System.Text.Json

The entire library has been migrated from Newtonsoft.Json to System.Text.Json.

Package Dependency Changes:

- <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
+ <PackageReference Include="System.Text.Json" Version="10.0.0" />

Impact:

  • All JSON attributes have changed from Newtonsoft to System.Text.Json equivalents
  • Custom serialization behavior may differ
  • dynamic properties may serialize differently

Attribute Changes

v4 (Newtonsoft.Json) v5 (System.Text.Json)
[JsonProperty("name")] [JsonPropertyName("name")]
[JsonConstructor] Removed (not needed)
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonConverter(typeof(CustomConverter))] [JsonConverter(typeof(CustomConverter))] (different base class)

Custom Serializer Options

A new centralized SignhostJsonSerializerOptions class is available:

// v5 - New centralized options
public static class SignhostJsonSerializerOptions
{
    public static JsonSerializerOptions Default { get; } =
        new JsonSerializerOptions {
            PropertyNameCaseInsensitive = true,
            DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
            Converters = { new JsonStringEnumConverter() },
        };
}

Migration: If you have custom serialization logic using Newtonsoft.Json with the library's data objects, you need to migrate to System.Text.Json.


Interface & Class Naming Changes

BREAKING: Interface Rename

v4 v5
ISignHostApiClient ISignhostApiClient
ISignHostApiClientSettings ISignhostApiClientSettings
SignHostApiClient SignhostApiClient
SignHostApiClientSettings SignhostApiClientSettings

Migration:

// v4
ISignHostApiClient client = new SignHostApiClient(settings);

// v5
ISignhostApiClient client = new SignhostApiClient(settings);

API Method Signature Changes

BREAKING: CreateTransactionAsync Now Uses Request Object

Before (v4):

Task<Transaction> CreateTransactionAsync(Transaction transaction);
Task<Transaction> CreateTransactionAsync(Transaction transaction, CancellationToken cancellationToken);

After (v5):

Task<Transaction> CreateTransactionAsync(CreateTransactionRequest request, CancellationToken cancellationToken = default);

Migration:

// v4
var transaction = new Transaction {
    Seal = false,
    Signers = new List<Signer> { signer },
    // ...
};
var result = await client.CreateTransactionAsync(transaction);

// v5
var request = new CreateTransactionRequest {
    Seal = false,
    Signers = new List<CreateSignerRequest> { signerRequest },
    // ...
};
var result = await client.CreateTransactionAsync(request);

BREAKING: New Request Objects

Three new request classes have been added for transaction creation:

  1. CreateTransactionRequest - For creating transactions
  2. CreateSignerRequest - For defining signers in a transaction request
  3. CreateReceiverRequest - For defining receivers in a transaction request

BREAKING: Method Overload Consolidation

Many method overloads without CancellationToken have been removed. All async methods now have optional CancellationToken parameters.

Removed Methods:

// These overloads no longer exist:
Task<Transaction> CreateTransactionAsync(Transaction transaction);
Task AddOrReplaceFileMetaToTransactionAsync(FileMeta fileMeta, string transactionId, string fileId);
Task AddOrReplaceFileToTransactionAsync(Stream fileStream, string transactionId, string fileId, FileUploadOptions uploadOptions);
Task AddOrReplaceFileToTransactionAsync(string filePath, string transactionId, string fileId, FileUploadOptions uploadOptions);
Task StartTransactionAsync(string transactionId);
Task<Transaction> GetTransactionAsync(string transactionId);
Task<ApiResponse<Transaction>> GetTransactionResponseAsync(string transactionId);
Task DeleteTransactionAsync(string transactionId);
Task DeleteTransactionAsync(string transactionId, DeleteTransactionOptions options);
Task<Stream> GetReceiptAsync(string transactionId);
Task<Stream> GetDocumentAsync(string transactionId, string fileId);

Migration:

// v4
await client.StartTransactionAsync(transactionId);

// v5
await client.StartTransactionAsync(transactionId); // CancellationToken is optional
// or explicitly:
await client.StartTransactionAsync(transactionId, cancellationToken);

BREAKING: Removed Non-Async Convenience Methods

Removed:

Task AddOrReplaceFileToTransaction(Stream fileStream, string transactionId, string fileId);
Task AddOrReplaceFileToTransaction(string filePath, string transactionId, string fileId);

Migration: Use the Async versions with optional parameters:

// v5
await client.AddOrReplaceFileToTransactionAsync(fileStream, transactionId, fileId);

BREAKING: FileUploadOptions is Now Optional with Default

Before (v4):

Task AddOrReplaceFileToTransactionAsync(Stream fileStream, string transactionId, string fileId, FileUploadOptions uploadOptions);

After (v5):

Task AddOrReplaceFileToTransactionAsync(Stream fileStream, string transactionId, string fileId, FileUploadOptions? uploadOptions = default, CancellationToken cancellationToken = default);

Data Object Changes

BREAKING: Transaction Class Changes

Property v4 Type v5 Type Notes
CreatedDateTime DateTimeOffset? DateTimeOffset No longer nullable
CancelledDateTime DateTimeOffset? DateTimeOffset? Property renamed to CanceledDateTime
Files IReadOnlyDictionary<string, FileEntry> IDictionary<string, FileEntry> No longer read-only

BREAKING: Property Rename:

  • CancelledDateTimeCanceledDateTime (match with actual API property)

Migration:

// v4
var cancelDate = transaction.CancelledDateTime;

// v5
var cancelDate = transaction.CanceledDateTime;

BREAKING: Signer Class Changes

Property v4 Type v5 Type Notes
Activities IReadOnlyList<Activity> IList<Activity> No longer read-only

Removed Properties from Signer:

  • ScribbleName - Moved to ScribbleVerification
  • ScribbleNameFixed - Moved to ScribbleVerification

BREAKING: Receiver Class Changes

Property v4 Type v5 Type
Activities IReadOnlyList<Activity> IList<Activity>?

BREAKING: FileMeta Changed

Property Changes:

Property v4 Type v5 Type
DisplayName string string?
Description string string?

BREAKING: Field Class Changes

Before (v4):

public class Field
{
    public string Type { get; set; }  // String type
    public string Value { get; set; }  // String only
    public Location Location { get; set; }
}

After (v5):

public class Field
{
    public FileFieldType Type { get; set; }  // Enum type
    [JsonConverter(typeof(JsonObjectConverter))]
    public object? Value { get; set; }  // Can be string, number, or boolean
    public Location Location { get; set; } = default!;
}

NEW: FileFieldType Enum

public enum FileFieldType
{
    Seal,
    Signature,
    Check,
    Radio,
    SingleLine,
    Number,
    Date,
}

Migration:

// v4
var field = new Field { Type = "Signature", Value = "value" };

// v5
var field = new Field { Type = FileFieldType.Signature, Value = "value" };

BREAKING: Activity Class Changes

Property v4 Type v5 Type
ActivityValue string string?
Info string string?

Attribute Change:

  • [JsonProperty("Activity")][JsonPropertyName("Activity")]

BREAKING: ActivityType Enum - Removed Values

The following ActivityType enum values have been removed:

Removed Value Code
InvitationReceived 102
IdentityApproved 110
IdentityFailed 111
Cancelled 201
Finished 500
Deleted 600
Expired 700
EmailBounceHard 901
EmailBounceSoft 902
EmailBounceBlocked 903
EmailBounceUndetermined 904

Migration: If your code relied on these enum values, you'll need to handle them differently or use the numeric codes directly.

BREAKING: DeleteTransactionOptions Changes

Property v4 Type v5 Type
Reason string string?

Verification System Refactoring

BREAKING: IVerification Interface Complete Refactor

Before (v4):

[JsonConverter(typeof(JsonVerificationConverter))]
public interface IVerification
{
    string Type { get; }
}

After (v5):

[JsonPolymorphic(TypeDiscriminatorPropertyName = "Type")]
[JsonDerivedType(typeof(ConsentVerification), "Consent")]
[JsonDerivedType(typeof(DigidVerification), "DigiD")]
// ... etc
public interface IVerification
{
    // No Type property - handled by polymorphic serialization
}

Key Changes:

  • The Type property is removed from all verification classes
  • Type discrimination is now handled by System.Text.Json polymorphic serialization
  • Custom JsonVerificationConverter has been removed

BREAKING: Removed Verification Types

The following verification classes have been completely removed:

Removed Class Notes
KennisnetVerification Was already marked [Obsolete]
ItsmeSignVerification Removed without replacement
SigningCertificateVerification Removed without replacement
UnknownVerification No longer needed with polymorphic serialization

Migration: Custom verification types are no longer supported; instead we will be more proactive with adding newer verification to this library.

BREAKING: Verification Classes No Longer Have Type Property

All verification classes lost their Type property:

Before (v4):

public class ConsentVerification : IVerification
{
    public string Type { get; } = "Consent";
}

After (v5):

public class ConsentVerification : IVerification
{
    // No Type property
}

NEW: JsonVerificationConverter Removed, Replaced by Polymorphic Serialization

If you had code that registered custom verifications:

// v4 - This no longer works
JsonVerificationConverter.RegisterVerification<MyCustomVerification>();

Migration: Custom verifications are no longer supported through the same mechanism. The verification types are now hardcoded via [JsonDerivedType] attributes.


Exception Handling Changes

BREAKING: UnauthorizedAccessException → BadAuthorizationException

HTTP 401 errors now throw BadAuthorizationException instead of UnauthorizedAccessException.

Before (v4):

try {
    await client.GetTransactionAsync(id);
} catch (UnauthorizedAccessException ex) {
    // Handle 401
}

After (v5):

try {
    await client.GetTransactionAsync(id);
} catch (BadAuthorizationException ex) {
    // Handle 401
}

BREAKING: SignhostException Removed

The SignhostException class (which was already marked [Obsolete]) has been removed.

Migration: Use SignhostRestApiClientException or one of its derived types.

BREAKING: ApiResponse.EnsureAvailableStatusCode → EnsureAvailableStatusCodeAsync

Before (v4):

public void EnsureAvailableStatusCode()

After (v5):

public async Task EnsureAvailableStatusCodeAsync(CancellationToken cancellationToken = default)

Migration:

// v4
response.EnsureAvailableStatusCode();

// v5
await response.EnsureAvailableStatusCodeAsync();

BREAKING: Exception Property Changes

Class Property v4 Type v5 Type
SignhostRestApiClientException ResponseBody string string?
GoneException<T> Result TResult TResult?

File Digest Changes

BREAKING: DigestHashAlgorithm Changed from String to Enum

Before (v4):

public class FileDigestOptions
{
    public string DigestHashAlgorithm { get; set; } = "SHA-256";
}

After (v5):

public class FileDigestOptions
{
    public DigestHashAlgorithm DigestHashAlgorithm { get; set; } = DigestHashAlgorithm.SHA256;
}

NEW: DigestHashAlgorithm Enum

public enum DigestHashAlgorithm
{
    None = 0,
    SHA256,
    SHA512,
}

BREAKING: Removed Weak Digest Algorithms

The following digest algorithms are no longer supported:

  • SHA1 / SHA-1
  • SHA384 / SHA-384
  • Any other algorithm name strings

Migration:

// v4
var options = new FileDigestOptions {
    DigestHashAlgorithm = "SHA-1"  // No longer valid
};

// v5
var options = new FileDigestOptions {
    DigestHashAlgorithm = DigestHashAlgorithm.SHA256  // Use SHA256 or SHA512 only
};

Removed Types and Members

Removed Classes

Class Notes
SignhostException Use SignhostRestApiClientException
KennisnetVerification Was obsolete, now removed
ItsmeSignVerification Removed
SigningCertificateVerification Removed
JsonVerificationConverter Replaced by polymorphic serialization

Removed Interface Members

ISignhostApiClient (now ISignhostApiClient):

  • All non-cancellation token overloads removed (see Method Signature Changes above)

Removed from Settings

SignhostApiReceiverSettings:

  • No constructor without validation (now validates sharedsecret is not null/empty)

Nullable Reference Types

BREAKING: Nullable Reference Types Enabled

The library now uses C# nullable reference types (<nullable>enable</nullable>).

Impact:

  • Many properties that were previously string are now string?
  • You may get new nullable warnings when using the library
  • Properties marked with = default! indicate they will be set by deserialization

Properties Changed to Nullable

Class Property v4 v5
Signer Id string string?
Signer IntroText string string?
Signer Language string string?
Signer Reference string string?
Signer Context dynamic dynamic?
Transaction Reference string string?
Transaction PostbackUrl string string?
Transaction Language string string?
Transaction Context dynamic dynamic?
ISignhostApiClientSettings UserToken string string?
ISignhostApiClientSettings AddHeader Action<AddHeaders> Action<AddHeaders>?

Other Breaking Changes

BREAKING: SignhostApiReceiver Changes

IsPostbackChecksumValid method signature changed:

Before (v4):

bool IsPostbackChecksumValid(
    IDictionary<string, string[]> headers,
    string body,
    out Transaction postbackTransaction);

After (v5):

bool IsPostbackChecksumValid(
    IDictionary<string, string[]> headers,
    string body,
    [NotNullWhen(true)] out Transaction? postbackTransaction);

Quick Migration Checklist

  • Update target framework (remove netstandard1.4 if used)
  • Rename interface usages: ISignHostApiClientISignhostApiClient
  • Rename class usages: SignHostApiClientSignhostApiClient
  • Update CreateTransactionAsync calls to use CreateTransactionRequest
  • Update Transaction.CancelledDateTimeCanceledDateTime
  • Update Field.Type from string to FileFieldType enum
  • Update FileDigestOptions.DigestHashAlgorithm from string to enum
  • Change UnauthorizedAccessException catch to BadAuthorizationException
  • Change EnsureAvailableStatusCode() to await EnsureAvailableStatusCodeAsync()
  • Remove usage of removed verification types (Kennisnet, ItsmeSign, SigningCertificate)
  • Remove usage of removed ActivityType enum values
  • Handle nullable reference type warnings
  • Update any custom JSON serialization code from Newtonsoft to System.Text.Json
  • Remove Signer ScribbleName/ScribbleNameFixed - use ScribbleVerification instead

Clone this wiki locally