Migration Guide for .NET SDK v7.0.0
Tags: vonage, dotnet, sdk, release
Published: 2024-04-09 11:26:51

Hello friends,

Our [.NET SDK](https://github.com/Vonage/vonage-dotnet-sdk) welcomed a new major release
recently - [v7.0.0](https://github.com/Vonage/vonage-dotnet-sdk/releases/tag/v7.0.0) is now available!

Being a major release, you might encounter side effects while updating to this version.
This is what this blog post is about: helping you identify and fix those problems.

The overall purpose of this release is to support new features which required a breaking change and start de-cluttering
the codebase.

## Prerequisites

This migration guide applies when migrating from v6.X.X - If you're still on v5.X.X, we highly recommend upgrading
to [v6.16.0](https://github.com/Vonage/vonage-dotnet-sdk/releases/tag/v6.16.0) first, using the
dedicated [migration guide](https://github.com/Vonage/vonage-dotnet-sdk?tab=readme-ov-file#upgrading-from-v5xx-to-v600).

## Migration Steps

### Everything Flagged With an 'Obsolete' Annotation Has Been Removed

When upgrading to a newer release, you may have noticed a warning indicating you're using an obsolete method.
Indeed, we flagged these changes with an `Obsolete` tag.

Please note that there's always a substitute when we decommission something.

#### Synchronous Methods

So far, many features are available with both synchronous/asynchronous implementation.
All synchronous methods have been removed in [v7.0.0](https://github.com/Vonage/vonage-dotnet-sdk/releases/tag/v7.0.0).
If you are still required to call a Vonage API in a synchronous context, you will have to call the asynchronous version
with
either `.Result` or `.Wait()` to wait for the result synchronously.

```csharp
// Using v6.X.X
applicationClient.DeleteApplication(applicationId);

// Using v7.X.X and above
await applicationClient.DeleteApplicationAsync(applicationId);
// Or
applicationClient.DeleteApplicationAsync(applicationId).Wait();
```

#### SubAccounts Features on 'AccountClient'

SubAccounts features were initially implemented by a contributor on the `AccountClient` while the product was still in
beta.
With the GA release, all SubAccounts features are available on the `SubAccountsClient`, which makes previous features
obsolete.

```csharp
// Using v6.X.X
var subAccount = await vonageClient.AccountClient.RetrieveSubAccountAsync(subAccountKey);
// Using v7.X.X and above
var request = GetSubAccountRequest.Parse(subAccountKey);
var subAccount = await vonageClient.SubAccountClient.GetSubAccountAsync(request);
```

#### 'CreateApplicaitonAsync' on 'ApplicationClient'

The current method contains a typo.

```csharp
// Using v6.X.X
var application = await applicationClient.CreateApplicaitonAsync(request);

// Using v7.X.X and above
var application = await applicationClient.CreateApplicationAsync(request);
```

#### 'CreateCall' on 'VoiceClient'

This method offers three different signatures.
Only the one with a `CallCommand` parameter will remain to avoid Primitive Obsession and rely on a proper
ValueObject.

```csharp
// Using v6.X.X
var callResponse = voiceClient.CreateCallAsync(toNumber, fromNumber, ncco);
var callResponse = voiceClient.CreateCallAsync(toEndpoint, fromNumber, ncco);
var callResponse = voiceClient.CreateCallAsync(callCommand);


// Using v7.X.X and above
var callResponse = voiceClient.CreateCallAsync(callCommand);
```

#### Constructors on 'Credentials'

Creating a Credentials instance should be done using a factory method or from a `Configuration` instance.
Constructors will be hidden, and the object will remain immutable.

We highly recommend you use
our [extension methods](https://developer.vonage.com/en/blog/implicit-configuration-in-net) to dynamically
initialize `Credentials` from your `appsettings.json` file.

```csharp
// Using v6.X.X
var credentials = new Credentials()
{
    ApiKey = apiKey,
};
var credentials = new Credentials(apiKey, apiSecret);
var credentials = Credentials.FromApiKeyAndSecret(apiKey, apiSecret);
var credentials = Credentials.FromAppIdAndPrivateKey(apiKey, apiSecret);


// Using v7.X.X and above
var credentials = Credentials.FromApiKeyAndSecret(apiKey, apiSecret);
var credentials = Credentials.FromAppIdAndPrivateKey(apiKey, apiSecret);
var credentials = configuration.BuildCredentials();
// Recommended
var credentials = serviceCollection.GetRequiredService<Credentials>();
```

#### Access to Vonage URLs

All URLs have been moved to a nested object (`VonageUrls`) to simplify the `Configuration` class and allow
multi-region URLs.

```csharp
// Using v6.X.X
var url = configuration.NexmoApiUrl;
var url = configuration.RestApiUrl;
var url = configuration.VideoApiUrl;
var url = configuration.EuropeApiUrl;

// Using v7.X.X and above
var url = configuration.VonageUrls.Nexmo;
var url = configuration.VonageUrls.Rest;
var url = configuration.VonageUrls.Video;
var url = configuration.VonageUrls.Get(VonageUrls.Region.EMEA);
```

#### Remove 'Input' Webhook Object

This item has been rendered obsolete due to the new multi-input functionality. Please add the `Dtmf` arguments to your
input action and use the `MultiInput` object, as recommended in
our [documentation](https://developer.vonage.com/en/voice/voice-api/ncco-reference#dtmf-input-settings).

#### Remove 'Portuguese" Language in Meetings API

This language has been removed in favor of 'Portuguese-Brazilian'.

```csharp
// Using v6.X.X
var language = UserInterfaceLanguage.Pt;


// Using v7.X.X and above
var language = UserInterfaceLanguage.PtBr;
```

#### Remove 'VoiceName' From 'TalkCommand' and 'TalkAction' in Voice

This parameter has been made [obsolete](https://developer.vonage.com/en/voice/voice-api/concepts/text-to-speech#locale)
by the language and style fields.

### Add New Timeouts on Voice Webhooks in Application API

Adding new timeouts requested (`connection_timeout`, `socket_timeout`) on Voice Webhooks.
Creating a specific structure, different from other webhooks, required to break the `Capability` inheritance.

### Rename Settings Key From 'appSettings' to 'vonage'

In order to make the settings more explicit and reduce the chances of conflict with other libraries, the base key has
been
updated.

Also, "Vonage." has been removed from every key to de-clutter the section. Finally, a few keys have been completely
renamed:

| Old Key                      | New Key      |
|------------------------------|--------------|
| Vonage.Vonage_key            | Api.Key      |
| Vonage.Vonage_secret         | Api.Secret   |
| Vonage.Vonage.Url.Api.Europe | Url.Api.EMEA |
| N/A                          | Url.Api.AMER |
| N/A                          | Url.Api.APAC |

Using v6.X.X

```json
{
  "appSettings": {
    "Vonage.UserAgent": "...",
    "Vonage.Url.Rest": "...",
    "Vonage.Url.Api": "...",
    "Vonage.Url.Api.Europe": "...",
    "Vonage.Url.Api.Video": "...",
    "Vonage.Vonage_key": "...",
    "Vonage.Vonage_secret": "...",
    "Vonage.Application.Id": "...",
    "Vonage.Application.Key": "...",
    "Vonage.Security_secret": "...",
    "Vonage.Signing_method": "...",
    "Vonage.RequestsPerSecond": "...",
    "Vonage.RequestTimeout": "..."
  }
}
```

Using v7.X.X and above

```json
{
  "vonage": {
    "UserAgent": "...",
    "Url.Rest": "...",
    "Url.Api": "...",
    "Url.Api.EMEA": "...",
    "Url.Api.AMER": "...", 
    "Url.Api.APAC": "...",
    "Url.Api.Video": "...",
    "Api.Key": "...",
    "Api.Secret": "...",
    "Application.Id": "...",
    "Application.Key": "...",
    "Security_secret": "...",
    "Signing_method": "...",
    "RequestsPerSecond": "...",
    "RequestTimeout": "..."
  }
}
```

### Make StartTime Nullable on Answered Webhook

As defined in the [specs](https://developer.vonage.com/en/voice/voice-api/webhook-reference#answered), the `StartTime`
is now nullable.

### Remove 'EventUrl' and 'EventMethod' From 'ConversationAction'

As defined in the [specs](https://developer.vonage.com/en/voice/voice-api/ncco-reference#conversation),
the `Conversation` action doesn't have an `EventUrl` or an `EventMethod`.

### Make 'From' Mandatory in VerifyV2 WhatsApp Workflow

The `From` property used to be optional - it is now mandatory.

```csharp
// Using v6.X.X
var workflow =  WhatsAppWorkflow.Parse(ValidToNumber);
var workflow =  WhatsAppWorkflow.Parse(ValidToNumber, ValidFromNumber);

// Using v7.X.X and above
var workflow =  WhatsAppWorkflow.Parse(ValidToNumber, ValidFromNumber);
```

## Conclusion

The migration guide is also available on
our [GitHub repository](https://github.com/Vonage/vonage-dotnet-sdk/blob/main/MIGRATION_v7.0.0.md).

Don't hesitate to report any issue on [GitHub](https://github.com/Vonage/vonage-dotnet-sdk) or join us on
the [Vonage Developer Slack](https://developer.vonage.com/en/community/slack), and we will get back to you.
You can also follow us on [X](https://www.twitter.com/VonageDev) to stay up-to-date with our latest news.

Happy coding, and see you soon!