-
Notifications
You must be signed in to change notification settings - Fork 14
Migration Guide v5
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.
- Target Framework Changes
- JSON Serialization Changes (Newtonsoft.Json → System.Text.Json)
- Interface & Class Naming Changes
- API Method Signature Changes
- Data Object Changes
- Verification System Refactoring
- Exception Handling Changes
- File Digest Changes
- Removed Types and Members
- Nullable Reference Types
- Other Breaking Changes
Before (v4):
netstandard2.0netstandard1.4net462
After (v5):
net10.0net9.0net8.0netstandard2.0net462
Migration:
-
netstandard1.4has been removed - Upgrade tonetstandard2.0or a specific .NET version. - If you were targeting
netstandard1.4, you must update your project to target at leastnetstandard2.0.
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
-
dynamicproperties may serialize differently
| 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) |
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.
| v4 | v5 |
|---|---|
ISignHostApiClient |
ISignhostApiClient |
ISignHostApiClientSettings |
ISignhostApiClientSettings |
SignHostApiClient |
SignhostApiClient |
SignHostApiClientSettings |
SignhostApiClientSettings |
Migration:
// v4
ISignHostApiClient client = new SignHostApiClient(settings);
// v5
ISignhostApiClient client = new SignhostApiClient(settings);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);Three new request classes have been added for transaction creation:
-
CreateTransactionRequest- For creating transactions -
CreateSignerRequest- For defining signers in a transaction request -
CreateReceiverRequest- For defining receivers in a transaction request
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);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);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);| 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:
-
CancelledDateTime→CanceledDateTime(match with actual API property)
Migration:
// v4
var cancelDate = transaction.CancelledDateTime;
// v5
var cancelDate = transaction.CanceledDateTime;| Property | v4 Type | v5 Type | Notes |
|---|---|---|---|
Activities |
IReadOnlyList<Activity> |
IList<Activity> |
No longer read-only |
Removed Properties from Signer:
-
ScribbleName- Moved toScribbleVerification -
ScribbleNameFixed- Moved toScribbleVerification
| Property | v4 Type | v5 Type |
|---|---|---|
Activities |
IReadOnlyList<Activity> |
IList<Activity>? |
Property Changes:
| Property | v4 Type | v5 Type |
|---|---|---|
DisplayName |
string |
string? |
Description |
string |
string? |
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!;
}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" };| Property | v4 Type | v5 Type |
|---|---|---|
ActivityValue |
string |
string? |
Info |
string |
string? |
Attribute Change:
-
[JsonProperty("Activity")]→[JsonPropertyName("Activity")]
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.
| Property | v4 Type | v5 Type |
|---|---|---|
Reason |
string |
string? |
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
Typeproperty is removed from all verification classes - Type discrimination is now handled by
System.Text.Jsonpolymorphic serialization - Custom
JsonVerificationConverterhas been removed
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.
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
}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.
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
}The SignhostException class (which was already marked [Obsolete]) has been removed.
Migration: Use SignhostRestApiClientException or one of its derived types.
Before (v4):
public void EnsureAvailableStatusCode()After (v5):
public async Task EnsureAvailableStatusCodeAsync(CancellationToken cancellationToken = default)Migration:
// v4
response.EnsureAvailableStatusCode();
// v5
await response.EnsureAvailableStatusCodeAsync();| Class | Property | v4 Type | v5 Type |
|---|---|---|---|
SignhostRestApiClientException |
ResponseBody |
string |
string? |
GoneException<T> |
Result |
TResult |
TResult? |
Before (v4):
public class FileDigestOptions
{
public string DigestHashAlgorithm { get; set; } = "SHA-256";
}After (v5):
public class FileDigestOptions
{
public DigestHashAlgorithm DigestHashAlgorithm { get; set; } = DigestHashAlgorithm.SHA256;
}public enum DigestHashAlgorithm
{
None = 0,
SHA256,
SHA512,
}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
};| Class | Notes |
|---|---|
SignhostException |
Use SignhostRestApiClientException
|
KennisnetVerification |
Was obsolete, now removed |
ItsmeSignVerification |
Removed |
SigningCertificateVerification |
Removed |
JsonVerificationConverter |
Replaced by polymorphic serialization |
ISignhostApiClient (now ISignhostApiClient):
- All non-cancellation token overloads removed (see Method Signature Changes above)
SignhostApiReceiverSettings:
- No constructor without validation (now validates
sharedsecretis not null/empty)
The library now uses C# nullable reference types (<nullable>enable</nullable>).
Impact:
- Many properties that were previously
stringare nowstring? - You may get new nullable warnings when using the library
- Properties marked with
= default!indicate they will be set by deserialization
| 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>? |
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);- Update target framework (remove
netstandard1.4if used) - Rename interface usages:
ISignHostApiClient→ISignhostApiClient - Rename class usages:
SignHostApiClient→SignhostApiClient - Update
CreateTransactionAsynccalls to useCreateTransactionRequest - Update
Transaction.CancelledDateTime→CanceledDateTime - Update
Field.Typefrom string toFileFieldTypeenum - Update
FileDigestOptions.DigestHashAlgorithmfrom string to enum - Change
UnauthorizedAccessExceptioncatch toBadAuthorizationException - Change
EnsureAvailableStatusCode()toawait EnsureAvailableStatusCodeAsync() - Remove usage of removed verification types (Kennisnet, ItsmeSign, SigningCertificate)
- Remove usage of removed
ActivityTypeenum values - Handle nullable reference type warnings
- Update any custom JSON serialization code from Newtonsoft to System.Text.Json
- Remove Signer
ScribbleName/ScribbleNameFixed- useScribbleVerificationinstead