You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
title: Best practices for using the Azure SDK with ASP.NET Core
3
-
description: Provides guidance and an overview of best practices for using the Azure SDK with ASP.NET Core
3
+
description: Learn best practices and the steps to properly implement the Azure SDK for .NET in your ASP.NET Core apps.
4
4
ms.topic: conceptual
5
5
ms.custom: devx-track-dotnet
6
-
ms.date: 10/08/2024
6
+
ms.date: 10/22/2024
7
7
---
8
8
9
9
# Implement the Azure SDK for .NET in ASP.NET Core apps
10
10
11
-
The Azure SDK for .NET enables ASP.NET Core apps to integrate with many different Azure services. In this article, you'll learn best practices and the steps to properly implement the Azure SDK for .NET in your ASP.NET Core apps. You'll learn how to:
11
+
The Azure SDK for .NET enables ASP.NET Core apps to integrate with many different Azure services. In this article, you'll learn best practices and the steps to implement the Azure SDK for .NET in your ASP.NET Core apps. You'll learn how to:
- Authenticate to Azure without using passwords or secrets.
16
16
- Configure common web app concerns such as logging and retries.
17
-
- Get started with additional topics such unit testing.
18
17
19
18
## Register service clients
20
19
21
-
The Azure SDK for .NET provides many service clients to connect your app to services such as Azure Blob Storage and Azure Key Vault. Register these services with the dependency container in the `Program.cs` file of your app to make them available to your app using Dependency Injection. The [Microsoft.Extensions.Azure](https://www.nuget.org/packages/Microsoft.Extensions.Azure) library provides helper methods to properly register your services and handles various concerns for you, such as setting up logging, handling service lifetimes, and assisting with authentication credential management.
20
+
The Azure SDK for .NET provides service clients to connect your app to Azure services such as Azure Blob Storage and Azure Key Vault. Register these services with the dependency container in the `Program.cs` file of your app to make them available to your app using Dependency Injection. The [Microsoft.Extensions.Azure](https://www.nuget.org/packages/Microsoft.Extensions.Azure) library provides helper methods to properly register your services and handles various concerns for you, such as setting up logging, handling service lifetimes, and authentication credential management.
22
21
23
-
To register the services you need, complete the following steps.
22
+
Complete the following steps to register the services you need:
24
23
25
-
1. Install the [Microsoft.Extensions.Azure](https://www.nuget.org/packages/Microsoft.Extensions.Azure) package.
24
+
1. Install the [Microsoft.Extensions.Azure](https://www.nuget.org/packages/Microsoft.Extensions.Azure) package:
26
25
27
26
```dotnetcli
28
27
dotnet add package Microsoft.Extensions.Azure
@@ -41,14 +40,16 @@ To register the services you need, complete the following steps.
@@ -79,10 +80,12 @@ To register the services you need, complete the following steps.
79
80
80
81
<h1>Reports</h1>
81
82
83
+
<ul>
82
84
@foreach(var report in reports)
83
85
{
84
-
<p>@report.Name</p>
86
+
<li>@report.Name</li>
85
87
}
88
+
</ul>
86
89
87
90
@code {
88
91
List<BlobItem> reports = new();
@@ -101,35 +104,80 @@ To register the services you need, complete the following steps.
101
104
102
105
---
103
106
107
+
## Authenticate using Microsoft Entra ID
108
+
109
+
Microsoft Entra ID is the recommended approach to authorize requests to Azure services. Use the [Azure Identity client library]() to implement secretless connections to Azure services in your code. The Azure Identity client library provides tools such as `DefaultAzureCredential` to simplify configuring secure connections. `DefaultAzureCredential` supports multiple authentication methods and determines which method should be used at runtime. This approach enables your app to use different authentication methods in different environments (local vs. production) without implementing environment-specific code.
110
+
111
+
Some Azure services also allow you to authorize requests using secrets keys. However, this approach should be used with caution. Developers must be diligent to never expose the access key in an unsecure location. Anyone who has the access key is able to authorize requests against the service and data.
112
+
113
+
Consider the following service client registrations:
In the preceding code, the `clientBuilder.UseCredential()` method accepts an instance of `DefaultAzureCredential` that will be reused across your registered services. `DefaultAzureCredential` discovers available credentials in the current environment and use them to connect to Azure services. The full order and locations in which `DefaultAzureCredential` looks for credentials can be found in the [`Azure Identity library overview`](/dotnet/api/overview/azure/Identity-readme#defaultazurecredential).
138
+
139
+
For example, when you run the app locally, `DefaultAzureCredential` discovers and uses credentials from the following developer tools:
140
+
141
+
- Environment variables
142
+
- Visual Studio
143
+
- Azure CLI
144
+
- Azure PowerShell
145
+
- Azure Developer CLI
146
+
147
+
`DefaultAzureCredential` also discovers credentials after you deploy your app from the following:
148
+
149
+
- Environment variables
150
+
- Workload identity
151
+
- Managed identity
152
+
104
153
## Set up service configurations
105
154
106
-
Azure service clients support configurations to change their default behaviors. You can define service client configurations directly in your code when you register a service. For example, in the [Register clients and subclients](#register-service-clients-and-subclients) section, you explicitly passed the Uri-typed variables to the client constructors. However, the recommended approach is to [store configurations in environment-dependent JSON files](/dotnet/core/extensions/configuration-providers#json-configuration-provider). For example, use an `appsettings.Development.json` file to store development environment settings and an `appsettings.Production.json` file to contain production environment settings. You can add any properties from the [`ClientOptions`](/dotnet/api/azure.core.clientoptions) class into the JSON file.
155
+
Azure service clients support configurations to change their default behaviors. There are two ways to configure service clients:
156
+
157
+
- You can [store configurations in environment-dependent JSON files](/dotnet/core/extensions/configuration-providers#json-configuration-provider). Configuration files are generally the recommended approach because they simplify app deployments between environments and help eliminate hard coded values.
158
+
- You can also configurations directly in your code when you register the service client. For example, in the [Register clients and subclients](#register-service-clients-and-subclients) section, you explicitly passed the Uri-typed variables to the client constructors.
159
+
160
+
The following example uses an `appsettings.Development.json` file to store development environment settings and an `appsettings.Production.json` file to contain production environment settings. You can add any properties from the [`ClientOptions`](/dotnet/api/azure.core.clientoptions) class into the JSON file.
107
161
108
162
1. Update the `appsettings.<environment>.json` file in your app to match the following structure:
- The top-level key names, `AzureDefaults`, `KeyVault`, `ServiceBus`, and `Storage`, are arbitrary. All other key names hold significance, and JSON serialization is performed in a case-insensitive manner.
180
+
- The top-level key names, `KeyVault`, `ServiceBus`, and `Storage`, are arbitrary names used to reference the config sections from your code. All other key names hold significance, and JSON serialization is performed in a case-insensitive manner.
133
181
- The `KeyVault:VaultUri`, `ServiceBus:Namespace`, and `Storage:ServiceUri` key values map to the `Uri`- and `string`-typed arguments of the <xref:Azure.Security.KeyVault.Secrets.SecretClient.%23ctor(System.Uri,Azure.Core.TokenCredential,Azure.Security.KeyVault.Secrets.SecretClientOptions)?displayProperty=fullName>, <xref:Azure.Messaging.ServiceBus.ServiceBusClient.%23ctor(System.String)?displayProperty=fullName>, and <xref:Azure.Storage.Blobs.BlobServiceClient.%23ctor(System.Uri,Azure.Core.TokenCredential,Azure.Storage.Blobs.BlobClientOptions)?displayProperty=fullName> constructor overloads, respectively. The `TokenCredential` variants of the constructors are used because a default `TokenCredential` is set via the <xref:Microsoft.Extensions.Azure.AzureClientFactoryBuilder.UseCredential(Azure.Core.TokenCredential)?displayProperty=fullName> method call.
134
182
135
183
1. Retrieve the settings in the JSON configuration file using `IConfiguration` and pass them into your service registrations:
@@ -147,18 +195,14 @@ Azure service clients support configurations to change their default behaviors.
At some point, you may want to change default Azure client configurations globally or for a specific service client. For example, you may want different retry settings or to use a different service API version. You can set the retry settings globally or on a per-service basis.
160
204
161
-
Update your configuration file to set a new default retry policy, as well as a specific retry policy for Azure Key Vault:
205
+
1. Update your configuration file to set default Azure settings, such as a new default retry policy and a specific retry policy for Azure Key Vault:
162
206
163
207
```json
164
208
{
@@ -181,13 +225,7 @@ Update your configuration file to set a new default retry policy, as well as a s
181
225
}
182
226
```
183
227
184
-
## Authenticate using Microsoft Entra ID
185
-
186
-
Microsoft Entra ID is the recommended approach to authorize requests to Azure services. Use the [Azure Identity client library]() to implement secretless connections to Azure services in your code. The Azure Identity client library provides tools such as `DefaultAzureCredential` to simplify configuring secure connections. `DefaultAzureCredential` supports multiple authentication methods and determines which method should be used at runtime. This approach enables your app to use different authentication methods in different environments (local vs. production) without implementing environment-specific code.
187
-
188
-
Some Azure services also allow you to authorize requests using secrets keys. However, this approach should be used with caution. Developers must be diligent to never expose the access key in an unsecure location. Anyone who has the access key is able to authorize requests against the service and data.
189
-
190
-
Consider the following service client registrations:
228
+
2. Add a call to the `ConfigureDefaults` extension method in your `AddAzureClients` setup:
In the preceding code, the `clientBuilder.UseCredential()` method accepts an instance of `DefaultAzureCredential` that will be reused across your registered services. `DefaultAzureCredential` discovers available credentials in the current environment and use them to connect to Azure services. The full order and locations in which `DefaultAzureCredential` looks for credentials can be found in the [`Azure Identity library overview`](/dotnet/api/overview/azure/Identity-readme#defaultazurecredential).
213
-
214
-
For example, when you run the app locally, `DefaultAzureCredential` discovers and uses credentials from the following developer tools:
215
-
216
-
- Environment variables
217
-
- Visual Studio
218
-
- Azure CLI
219
-
- Azure PowerShell
220
-
- Azure Developer CLI
221
-
222
-
`DefaultAzureCredential` also discovers credentials after you deploy your app from the following:
223
-
224
-
- Environment variables
225
-
- Workload identity
226
-
- Managed identity
227
-
228
250
## Configure logging
229
251
230
-
The Azure SDK for .NET client libraries include the ability to log client library operations. This logging allows you to monitor requests and responses between services clients and Azure services. When you register the Azure SDK library's client via a call to the <xref:Microsoft.Extensions.Azure.AzureClientServiceCollectionExtensions.AddAzureClients%2A> extension method, some logging configurations are handled for you.
231
-
232
-
```csharp
233
-
```csharp
234
-
builder.Services.AddAzureClients(clientBuilder=>
235
-
{
236
-
clientBuilder.AddSecretClient(
237
-
builder.Configuration.GetSection("KeyVault"));
238
-
239
-
clientBuilder.AddBlobServiceClient(
240
-
builder.Configuration.GetSection("Storage"));
252
+
The Azure SDK for .NET client libraries can log client library operations to monitor requests and responses to Azure services. When you register an Azure SDK client using the <xref:Microsoft.Extensions.Azure.AzureClientServiceCollectionExtensions.AddAzureClients%2A> extension method, the <xref:Microsoft.Extensions.Azure.AzureEventSourceLogForwarder> is registered with the dependency injection container. This service forwards log messages from Azure SDK event sources to <xref:Microsoft.Extensions.Logging.ILoggerFactory> to enables you to use the standard ASP.NET Core logging configuration for logging.
241
253
242
-
clientBuilder.AddServiceBusClientWithNamespace(
243
-
builder.Configuration["ServiceBus:Namespace"]);
254
+
The following table depicts how the Azure SDK for .NET `EventLevel` maps to the ASP.NET Core `LogLevel`.
You can change default log levels and other settings using the same JSON configurations outlined in the [configure authentication](#configure-authentication) section. For example, toggle a the `ServiceBusClient` log level to `Debug` by setting the `Logging:LogLevel:Azure.Messaging.ServiceBus` key as follows:
261
266
@@ -270,38 +275,3 @@ You can change default log levels and other settings using the same JSON configu
270
275
}
271
276
}
272
277
```
273
-
274
-
## Unit testing considerations
275
-
276
-
Unit testing is an important part of a sustainable development process that can improve code quality and prevent regressions or bugs in your apps. This section provides a basic introduction to Unit Testing with the Azure SDK for .NET. Visit the [Unit testing and mocking with the Azure SDK for .NET](/dotnet/azure/sdk/unit-testing-mocking) article for a detailed exploration of these unit testing concepts.
277
-
278
-
Unit testing presents challenges when the code you're testing performs network calls, such as those made to Azure resources by Azure service clients. Tests that run against live services can experience issues, such as latency that slows down test execution, dependencies on code outside of the isolated test, and issues with managing service state and costs every time the test is run. Instead of testing against live Azure services, replace the service clients with mocked or in-memory implementations to avoid these issues.
279
-
280
-
Each of the Azure SDK clients follows [mocking guidelines](https://azure.github.io/azure-sdk/dotnet_introduction.html#dotnet-mocking) that allow their behavior to be overridden:
281
-
282
-
* Each client offers at least one protected constructor to allow inheritance for testing.
283
-
* All public client members are virtual to allow overriding.
284
-
285
-
To create a test service client, you can either use a mocking library or standard C# features such as inheritance. Mocking frameworks allow you to simplify the code that you must write to override member behavior. (These frameworks also have other useful features that are beyond the scope of this article.)
0 commit comments