Dotnet Azure
Dotnet Azure
OVERVIEW QUICKSTART
Introduction to Azure and .NET Create an ASP.NET Core web app
in Azure
QUICKSTART TUTORIAL
Build a serverless function ASP.NET Core and Docker
DEPLOY TUTORIAL
Deploy a .NET app with Azure Authentication end-to-end in
DevOps App Service
Featured content
Learn to develop .NET apps leveraging a variety of Azure services.
Are you interested in contributing to the .NET docs? For more information, see our contributor guide.
Introduction to Azure and .NET
Article • 08/15/2024
Application hosting on Azure - Azure can host your entire application stack from
web applications and APIs to databases to storage services. Azure supports a
variety of hosting models from fully managed services to containers to virtual
machines. When using fully managed Azure services, your applications can take
advantage of the scalability, high-availability, and security built in to Azure.
Next steps
Next, learn about the most commonly used Azure services for .NET development.
Key Azure Services for .NET developers
Article • 08/21/2024
While Azure contains over 100 services, the following Azure services are the services you
will use most frequently as a .NET developer.
ノ Expand table
Azure AI Azure AI Services are a collection of cloud-based services that allow you to
Services add AI based capabilities to your application. Examples include Azure
OpenAI, Azure Vision, Azure Speech, Azure Language, and Azure Translator.
Azure App Azure App Service is a fully managed platform for hosting web applications
Service and APIs in Azure. It features automatic load balancing and auto-scaling in a
highly available environment. You pay only for the compute resources you
use and free tiers are available.
Azure Azure Container Apps are fully managed environments that enable you to
Container run microservices and containerized applications on a serverless platform.
Apps Applications built on Container Apps provide scalability, resiliency, and
other advantages of complex container orchestrators while leaving behind
many of the complexities.
Azure Azure Functions is a serverless compute service that lets you write small,
Functions discrete segments of code that can be executed in a scalable and cost-
effective manner, all without managing any servers or runtimes. Functions
can be invoked by a variety of different events and easily integrate with
other Azure services through the use of input and output bindings.
Azure SQL Azure SQL is a fully managed cloud based version of SQL Server. Azure
automatically performs traditional administrative tasks like patching and
backups for you and features built-in high availability.
Azure Azure Cosmos DB is a fully managed NoSQL database with single digit
Cosmos DB response times, automatic scaling, and a MongoDB compatible API.
Azure Blob Azure Blob Storage allows your applications to store and retrieve files in the
Storage cloud. Azure Storage is highly scalable to store massive amounts of data
and data is stored redundantly to ensure high availability.
Azure Azure Service Bus is a fully managed enterprise message broker supporting
Service Bus both point to point and publish-subscribe integrations. It is ideal for
building decoupled applications, queue based load leveling, or facilitating
communication between microservices.
Icon Service Description
Azure Key Every application has application secrets like connection strings and API
Vault keys it must store. Azure Key Vault helps you store and access those secrets
securely, in an encrypted vault with restricted access to make sure your
secrets and your application are not compromised.
For the full list of Azure products and services, visit the Azure documentation home
page.
Next steps
Start configuring your Azure development environment by Creating an Azure Account.
Create an Azure account
Article • 08/15/2024
To use Azure, you need an Azure account. Your Azure account is the credential you use
to sign into Azure services like the Azure Portal or Cloud Shell .
Next steps
After creating an Azure account, be sure to bookmark the Azure Portal in your web
browser for easy access to Azure.
Next, you will want to configure Visual Studio or Visual Studio Code for Azure
development depending on which IDE you use.
Visual Studio includes tooling to help with the development and deployment of
applications on Azure. This guide helps you make sure that Visual Studio is properly
configured for Azure development.
) Important
You'll need to install the Azure development workload to enable Visual Studio
tooling for Azure authentication, development, and deployment.
1. Inside Visual Studio, navigate to Tools > Options to open the options dialog.
2. In the Search Options box at the top, type Azure to filter the available options.
4. Select the drop-down menu under Choose an account and choose to add a
Microsoft account.
5. In the window that opens, enter the credentials for your desired Azure account,
and then confirm your inputs.
Next steps
If you also use Visual Studio Code for development in .NET or any other language,
you should configure Visual Studio Code for Azure development. Otherwise, proceed to
Installing the Azure CLI.
Configure Visual Studio Code for Azure
development
Article • 08/15/2024
If you're using Visual Studio Code, whether for .NET development, for building single
page applications using frameworks like Angular, React or Vue, or for writing
applications in another language like Python, you'll want to configure Visual Studio
Code for Azure development.
To learn more about installing extensions in Visual Studio Code, refer to the Extension
Marketplace document on the Visual Studio Code website.
After you've signed-in, you'll see all of your existing resources in the Resources view.
You can create and manage these services directly from Visual Studio Code. You'll also
see a Workspace view that includes local tasks specific to your workspace and files on
your machine, such as attaching to a Database or deploying your current workspace to
Azure.
Next steps
Next, you'll want to install the Azure CLI on your workstation.
In addition to the Azure portal, Azure also offers the Azure CLI as a command-line tool
to create and manage Azure resources. The Azure CLI offers the benefits of efficiency,
repeatability, and the ability to script recurring tasks.
In practice, most developers use both the Azure portal and the Azure CLI. Whereas the
Azure portal is useful when exploring new services and getting an overview of all of the
resources in your Azure account, most developers find the Azure CLI to be faster and
more efficient. The Azure CLI can often accomplish in a single command what takes
multiple steps in the Azure portal. In addition, since Azure CLI commands can be saved
to a file, you can ensure that recurrent tasks are run the same way each time.
In addition to configuring your IDE and installing the Azure CLI, multiple other tools and
utilities are available to help you be more productive with Azure.
Azure PowerShell
Azure PowerShell is a PowerShell module of cmdlets for managing Azure resource
directly from PowerShell, either from the command line or from within PowerShell
scripts. Azure PowerShell supports PowerShell features like PowerShell objects and
combining commands into pipelines. If you have used PowerShell before or need to
write complex automation scripts to manage Azure resources, you will want to install
Azure PowerShell.
You can use azd with extensible templates that include everything you need to get an
application up and running in Azure. These templates include application code, and
reusable infrastructure as code assets.
Next steps
Validate your development environment is set up correctly using the .NET on Azure
development environment checklist.
.NET on Azure development
environment checklist
Article • 08/21/2024
This checklist is provided to help you make sure you have your development
environment correctly configured for .NET development with Azure
If you are a Visual Studio subscriber, you have monthly free Azure credits
available to you every month
Create a free Azure account and receive $200 in credits and select services free
for 12 months
Use an account assigned to you by your company's Azure administrator
This guide describes how to use the application and code assessment for .NET to
evaluate how ready your .NET applications are for moving to Azure and what changes
you need to make for a successful cloud migration.
It discovers application technology usage through static code analysis, supports effort
estimation, and accelerates code replatforming by giving you recommendations on how
to overcome any potential issues and make your code cloud-compatible.
Application and code assessment is available in a Visual Studio extension and in a CLI
tool.
Application and code assessment for .NET bundles a set of tools, engines, and rules to
assess and replatform .NET applications to various Azure targets such as Azure App
Service, Azure Kubernetes Service and Azure Container Apps.
Assess the code compatibility with Azure: get notified about every part of your
code that might not work when you move your application to Azure.
Supported languages
Application and code assessment for .NET can analyze projects written in the following
languages:
C#
Visual Basic
ASP.NET
Class libraries
Next steps
Prerequisites
Windows operating system
Visual Studio 2022 version 17.1 or later - for the Visual Studio extension
.NET SDK - for the command-line tool
1. With Visual Studio opened, press the Extensions > Manage Extensions menu item,
which opens the Manage Extensions window.
2. In the Manage Extensions window, enter "Azure Migrate" into the search input
box.
3. Select the Azure Migrate application and code assessment item, and then select
Download.
4. Once the extension has been downloaded, close Visual Studio. This starts the
installation of the extension.
5. In the VSIX Installer dialog select Modify and follow the directions to install the
extension.
.NET CLI
) Important
Installing this tool may fail if you've configured additional NuGet feed sources. Use
the --ignore-failed-sources parameter to treat those failures as warnings instead
of errors.
.NET CLI
Next steps
Azure Migrate application and code assessment for .NET helps you to identify any issues
your application might have when it is ported to Azure and improve the performance,
scalability and security by suggesting modern, cloud-native solutions.
This guide describes how to use the Visual Studio extension to scan your application for
possible incompatibilities with Azure.
If you have not installed the Visual Studio extension, please follow these instructions
first.
1. Open the solution containing the projects you want to migrate to Azure in Visual
Studio 2022.
2. Right-click on any of the projects in the Solution Explorer window and select Re-
platform to Azure.
3. The utility will start and give you the option to start a new analysis report or open
an existing one. It will also display any recent analysis reports.
4. Click on New report and it will display the projects in your solution in a treeview. It
will give you an option to select which projects to analyze. You will find web
projects pre-selected for you and you can change the selection by checking or
unchecking the boxes next to the projects. When the tool runs, it also analyzes the
dependencies your selected projects has.
5. Click the Next button and you'll be presented with the option to analyze Source
code and settings, Binary dependencies, or both.
7 Note
The source code and settings option will only scan the source code in the
projects you selected on the previous screen. The Binary dependencies
option will scan any dependencies (such as NuGet packages or referenced
dlls) your projects rely on. You can expect to see many more issues identified
when binary dependencies is selected. Scanning binaries can be valuable
because the issues detected may identify potential problem in dependencies,
but also might not be as useful because source code is not available for these
dependencies, so the issues can't be fixed and, in the case of potential issues,
it may not be an issues in your case.
It might be helpful to generate two different reports: for action items and for your
awareness. >
1. Click the Analyze button to start the scan. The selected projects are scanned to
look for potential issues when migrating to Azure. When finished, you'll see a
dashboard of results.
Next steps
Azure Migrate application and code assessment for .NET integrates with the GitHub
Copilot extension for Visual Studio. Together, they provide conversational analysis about
your migration reports. GitHub Copilot can help you learn more about the overall results
and specific issues and determine next steps. In this article, you learn how to use GitHub
Copilot to analyze the results of a completed Azure migration report.
7 Note
Copilot integration is not available natively using the .NET CLI version of Azure
Migrate application and code assessment for .NET.
Prerequisites
Install Visual Studio 2022 version 17.10 or later
Install GitHub Copilot for Visual Studio extension
Install a version of .NET that supports the app you're trying to migrate
Scan your application in Visual Studio to use Copilot conversational analysis.
Copilot relies on a completed scan report to provide suggestions.
1. In the NEXT STEPS section of the Azure compatibility report, select the Open chat
button to launch a chat session with GitHub Copilot.
2. Visual Studio sends a default prompt asking for assistance with migrating the
scanned solution. Copilot responds with a summary of the identified issues and
provides clickable links to select specific issues to follow up on.
3. Select one of the proposed issues in the chat response to begin further analysis.
You can also send your own custom chat prompts to Copilot using the input box at
the bottom of the Copilot extension window.
1. On the main dashboard page of the Azure compatibility report, select Aggregate
issues on the left navigation to switch to the issues view. The new view displays a
list of issues and related information, such as their estimated severity and state.
2. Select the arrow icon next to an issue you're interested in to see more details, and
then select the Ask Copilot button to start a new Copilot chat about that specific
issue.
7 Note
The Ask Copilot feature shares the description of the issue and details about
the code snippet that triggered the issue with GitHub Copilot. Only select Ask
Copilot if you're comfortable sending the details of that issue to Copilot.
In the preceding screenshot, the scan discovered that the app is using Windows
authentication, which is not available on Azure, so Copilot responds with
alternatives and general implementation steps.
3. Ask clarifying questions using the chat input at the bottom of the Copilot
extension window.
Next steps
Interpret the analysis results from the Azure Migrate application and code
assessment for .NET.
Customize analysis using run configs
Frequently asked questions
Analyze applications with the .NET CLI
Article • 11/14/2023
Azure Migrate application and code assessment for .NET helps you to identify any issues
your application might have when it is ported to Azure and improve the performance,
scalability and security by suggesting modern, cloud-native solutions.
This guide describes how to use the CLI tool to scan your application for possible
incompatibilities with Azure.
If you have not installed the .NET CLI tool, please follow these instructions first.
7 Note
If this is your first time running application and code assessment for .NET, you
will see an informational message about telemetry and how to opt-out if you
should want to.
2. A screen is presented that allows you to pick the projects in your solution to
analyze. Use the arrow keys to highlight individual projects and press Space to
select them. Press Enter when you're ready.
3. Next you'll be presented with the option to analyze Source code and settings,
Binary dependencies, or both. Make your choice and press Enter.
7 Note
The source code and settings option will only scan the source code in the
projects you selected on the previous screen. The Binary dependencies
option will scan any dependencies (such as NuGet packages) your projects
rely on. You can expect to see many more issues identified when binary
dependencies is selected. This option can create some "noise" since it will also
identify potential compatibility issues of the binaries that are not necessarily
apply to your application.
4. You'll then be prompted to generate a report with the results of the analysis. The
output can be formatted as CSV, HTML, or JSON. Press Enter.
5. You'll be prompted for a report name. Input the name and press Enter.
6. Finally, you'll be asked whether you want to perform the scan. Press y to continue,
or n to go back and change options.
7. Once the analysis completes, the report is saved, and a summary of the results are
displayed.
Next Steps
Both CLI tool and Visual Studio allow you to create HTML, CSV and JSON reports. This
section describes how to interpret these reports.
For the purposes of this document we're going to use the HTML report.
Dashboard view
The report presents its results in a dashboard format.
The main dashboard shows a Summary section with the results of the scan, Severity
graph and Categories of the issues and incidents.
The Summary section of the dashboard contains several terms that are worth defining
as you'll see them in other screens.
Projects view
Click on the Projects link below the Dashboard on the left side of the report to see the
number of issues, incidents, and the estimated effort to fix those incidents by each
project scanned.
You can drill down to see the issues found in each project by clicking on the project
name. This will show a screen similar to the overall dashboard but scoped to the
selected project.
At the top of the project dashboard you'll find 3 tabs: Dashboard, Components, and
Issues.
Click on the Components tab to see which files the incidents of the issues identified
reside in. You can drill down into the file to see the issues that triggered the incident, a
description of the issue, the exact position in the code where the incidents exist, and an
estimation of the effort it will take to fix the incidents.
Finally, by clicking on the Issues tab, you can see the incidents organized by the issues
which triggered them. You can drill down into the issues to see the exact file location
that needs to be addressed and the effort to fix.
In the section on the right, you will find an explanation for the selected issue with
suggestions on how to fix it or the verifications you should make to ensure your
application will work properly in Azure. There are also links to the detailed
documentation in the bottom part of that section.
How to customize analysis using run
configs
Article • 09/06/2024
The Azure Migrate application and code assessment tool supports custom analysis using
run configs. Before the tool runs an analysis, it discovers all available rules and analyzers
and then uses the ones that match current project's traits. However, some results might
be too noisy for some applications.
To control/scope rules and/or analyzers used, you can provide a JSON run configuration
file. This allows you to:
The Azure Migrate application and code assessment tool enables you to Analyze
applications with the .NET CLI. When using the CLI, there are two options to provide
a run config:
Interactive mode: The CLI asks if you want to provide run config. Select Yes
and then provide the path to the run config file.
Non-interactive mode: Provide the -c or --config argument, which allows
you to provide the path to the run config JSON.
JSON
{
"analysis": {
"settings": {
"binaries": {
"useDefaultExclusions": true,
"include": [
"**/*webmvc.dll",
"**/*Transit.dll"
],
"exclude": [
]
}
},
"rules": [
{
"id": "Identity.0001",
"severity": "potential",
"effort": 5
},
{
"id": "Local.0001",
"enabled": false
},
{
"id": "Local.0003",
"enabled": false
}
],
"analyzers": [
{
"id": "Identity.0001.Types",
"enabled": false
},
{
"ruleId": "Local.0004",
"id": "Local.0004.Profiles",
"kind": "namespace",
"properties": {
"namespaces": [
"Microsoft.Win32"
]
}
}
]
}
}
binaries to be analyzed. It's recommended to run binary analysis once to see any
red flags, but results for binaries tend to be verbose. Some of the results could flag
problems inside dependencies your application is consuming. Other results could
be valid problems in your app, but located in unused code paths. These can be
ignored to reduce the verbosity of the results.
analysis.rules contains rules definitions. These definitions override or disable
{
"rules": [
{
"id": "Category.NumericId",
"severity": "potential",
"effort": 5
}
]
}
{
"rules": [
{
"id": "Category.NumericId",
// specify new property values
}
]
}
{
"rules": [
{
"id": "Category.NumericId",
"enabled": false
}
]
}
{
"analyzers": [
{
"id": "analyzerId",
"enabled": false
}
]
}
{
"analyzers": [
{
"ruleId": "rule id",
"id": "analyzer id",
"kind": "analyzer kind",
"properties": {
// properties specific for analyzer kind
}
}
]
}
Frequently asked questions
Article • 09/06/2024
This page answers some of the most common questions about the Azure Migrate
application and code assessment tool.
This article provides considerations and comparisons between the multiple choices you
have in Azure when migrating your existing .NET Framework applications from on-
premises to Azure.
The fundamental areas to consider when migrating existing .NET applications to Azure
are:
1. Compute choices
2. Database choices
3. Networking and security considerations
4. Authentication and authorization considerations
Compute choices
When migrating existing .NET Framework applications to Azure you have multiple
choices. However, since .NET Framework depends on Windows, the following choices
are limited to Windows-based compute services.
The following table shows several comparisons and recommendations to help you
choose the right compute migration path for your existing .NET application.
ノ Expand table
How to See Migrate to Azure See Migrate Azure App Follow considerations,
migrate Virtual Machines Service scenarios, and
walkthroughs explained
in the Modernizing
existing .NET apps with
Azure and Windows
Containers eBook
The following flowchart diagram shows a decision tree when planning a migration to
Azure for your existing .NET Framework applications. If it's viable, try option A first, but
option B is the easiest path to perform.
Database choices
When migrating relational databases to Azure you have multiple choices. See Migrate
your SQL Server database to Azure to help you choose the right database migration
path for your existing .NET application.
To get started building your own virtual network, see the Azure Virtual Network
documentation.
Authentication and authorization
considerations when migrating to Azure
A top concern of any organization moving to the cloud is security. Most companies have
invested a substantial amount of time, money, and engineering into designing and
developing a security model, and it's important that they're able to leverage existing
investments such as identity stores and single sign-on solutions.
Many existing enterprise B2E .NET applications running on-premises use Active
Directory for authentication and identity management. Azure AD Connect enables you
to integrate your on-premises directories with Azure Active Directory. To get started, see
Integrate your on-premises directories with Azure Active Directory.
See Identity requirements for your hybrid identity solution for further planning related
to Azure Active Directory.
Other authentication protocol choices are OAuth and OpenID , which are common
in consumer-facing applications. When using autonomous identity databases, such as
an ASP.NET Identity SQL database wrapped by IdentityServer4 using OAuth, no
connectivity to on-premises databases or directories is usually required.
Next steps
Migrate an ASP.NET web application to Azure App Service
Migrate your .NET web app or service to
Azure App Service
Article • 07/30/2022
App Service is a fully managed compute platform service that's optimized for hosting
scalable websites and web applications. This article provides information on how to lift-
and-shift an existing application to Azure App Service, modifications to consider, and
additional resources for moving to the cloud . Most ASP.NET websites (Webforms,
MVC) and services (Web API, WCF) can move directly to Azure App Service with no
changes. Some may need minor changes while others may need some refactoring.
Ready to get started? Publish your ASP.NET + SQL application to Azure App Service.
Considerations
Create a VPN connecting App Service to on-premises resources using Azure Virtual
Networks.
Securely expose on-premises services to the cloud without firewall changes using
Azure Relay.
Migrate dependencies such as a SQL database to Azure.
Use platform-as-a-service offerings in the cloud to reduce dependencies. For
example, rather than connect to an on-premises mail server, consider using
SendGrid.
Port Bindings
Azure App Service supports port 80 for HTTP and port 443 for HTTPS traffic.
ノ Expand table
Binding Notes
BasicHttp
Binding Notes
WSHttp
BasicHttpContextBinding
WebHttpBinding
WSHttpContextBinding
Authentication
Azure App Service supports anonymous authentication by default and Forms
authentication when intended. Windows authentication can be used by integrating with
Azure Active Directory and ADFS only. Learn more about how to integrate your on-
premises directories with Azure Active Directory.
IIS settings
Everything traditionally configured via applicationHost.config in your application can
now be configured through the Azure portal. This applies to AppPool bitness,
enable/disable WebSockets, managed pipeline version, .NET Framework version
(2.0/4.0), and so on. To modify your application settings, navigate to the Azure portal ,
open the blade for your web app, and then select the Application Settings tab.
IIS5 Compatibility Mode is not supported. In Azure App Service, each web app and all of
the applications under it run in the same worker process with a specific set of
application pools.
In Azure App Service, each web app and all of the applications under it run in the same
application pool. Consider establishing a single application pool with common settings
or creating a separate web app for each application.
Physical directories
Azure App Service does not allow physical drive access. You may need to use Azure Files
to access files via SMB. Azure Blob Storage can store files for access via HTTPS.
ISAPI filters
Azure App Service can support the use of ISAPI Filters, however, the ISAPI DLL must be
deployed with your site and registered via web.config.
DNS
You may need to update DNS configurations based on the requirements of your
application. These DNS settings can be configured in the App Service custom domain
settings.
See also
How to determine if your app qualifies for App Service
Moving your database to the cloud
Azure web app sandbox details and restrictions
Migrate an ASP.NET Web application to
an Azure Virtual Machine
Article • 06/04/2024
Quickstart
Learn how to create a virtual machine and publish your app to it: Publish to an Azure
VM
Get Started
These tutorials demonstrate the steps to create (or migrate) a virtual machine, publish
your web application to it, and other tasks that may be required to support your
application in Azure.
Create a virtual machine for your ASP.NET application in Azure using one of the
following options:
Create a new virtual machine for ASP.NET Applications
Migrate an existing on-premises VMWare virtual machine
Migrate an existing on-premises Hyper-V virtual machine
Publish a cloud service using Visual Studio
Create a secure virtual network for your VMs
Create a CI/CD pipeline for your application
Move to a VM scale set for high availability and scalability
Considerations
Benefits
Virtual machines offer the easiest path to migrate an application from on-premises to
the cloud. They enable you to replicate the same environment your application uses on-
premises, while removing the need to maintain your own data centers. Virtual Machine
Scale Sets provide high availability and scalability for applications running in Virtual
Machines.
Virtual Machine Size
Choose the virtual machine size and type that is best optimized for your workload. For
more information, see Sizes for Windows virtual machines in Azure.
Maintenance
Just like an on-premises machine, you are responsible for maintaining and updating the
virtual machine*. If your application can run in a Platform as a Service (PaaS)
environment such as Azure App Service or in a container, that will remove this need.
*Automatic OS upgrades for virtual machine scale sets is currently available as a Preview
service.
Virtual Networks
Azure Virtual Networks enable you to:
Active Directory
Many applications use Active Directory for authentication and identity management.
SQL Databases
If your application is using an on-premises database, your app will not be able to talk to
it by default. You can either:
Configure a hybrid network that enables your application to access your database
running on-premises.
Migrate your database to the Azure. For more information, see Migrate your SQL
Server database to Azure.
You want to make sure that your application is highly available and can scale, migrate
your VM image to an Azure Virtual Machine Scale Set to improve the availability and
scalability of your application. VM Scale Sets provide the ability to use an existing VM
you've already configured or set up a build pipeline to build an image with your
application.
To get started, see Deploy your application on virtual machine scale sets.
Centralized Logging
When running your application across multiple instances, consider storing your logs in a
centralized location such as Azure Storage.
Next steps
Migrate a SQL Server database to Azure
Migrate a SQL Server database to Azure
Article • 05/12/2022
This article provides a brief outline of two options for migrating a SQL Server database
to Azure. Azure has three primary options for migrating a production SQL Server
database. This article focuses on the following two options:
1. SQL Server on Azure VMs: A SQL Server instance installed and hosted on a
Windows Virtual Machine running in Azure, also known as Infrastructure as a
Service (IaaS).
2. Azure SQL Database: A fully managed SQL database Azure service, also known as
Platform as a Service (PaaS).
Both come with pros and cons that you will need to evaluate before migrating. The third
option is Azure SQL Database managed instances.
Get started
The following migration guides will be useful, depending on which service you use:
Additionally, the following links to conceptual content will help you understand VMs
better:
High availability and disaster recovery for SQL Server in Azure Virtual Machines
Performance best practices for SQL Server in Azure Virtual Machines
Application Patterns and Development Strategies for SQL Server in Azure Virtual
Machines
And the following links will help you understand Azure SQL Database better:
You are looking to "lift and shift" your database and applications with minimal to
no changes.
You prefer having full control over your database server and the VM it runs on.
You already have SQL Server and Windows Server licenses that you intend to use.
You are looking to modernize your applications and are migrating to use other
PaaS services in Azure.
You do not wish to manage your database server and the VM it runs on.
You do not have SQL Server or Windows Server licenses, or you intend to let
licenses you have expire.
The following table describes differences between each service based on a set of
scenarios.
ノ Expand table
Managing costs You must manage SQL Server You must manage service costs (based on
license costs, Windows Server eDTUs or DTUs, storage, and number of
license costs, and VM costs databases if using an elastic pool). You
(based on cores, RAM, and must also manage the cost of any SLA.
storage).
To learn more about the differences between the two, see Choose the right deployment
option in Azure SQL.
FAQ
Can I still use tools such as SQL Server Management Studio and SQL Server
Reporting Services (SSRS) with SQL Server in Azure VMs or Azure SQL Database?
Yes. All Microsoft SQL tooling works with both services. SSRS is not part of Azure
SQL Database, though, and it's recommended that you run it in an Azure VM and
then point it to your database instance.
I want to go PaaS but I'm not sure if my database is compatible. Are there tools
to help?
Yes. The Data Migration Assistant is a tool that is used as a part of migrating to
Azure SQL Database. The Azure Database Migration Service is a preview service
that you can use for either IaaS or PaaS.
Yes. The Azure Pricing Calculator can be used for estimating costs for all Azure
services, including VMs and database services.
Next steps
Choose the right Azure hosting option
Develop .NET apps with AI features
Article • 05/02/2025
With .NET, you can use artificial intelligence (AI) to automate and accomplish complex tasks in
your applications using the tools, platforms, and services that are familiar to you.
Language processing: Create virtual agents or chatbots to talk with your data and
generate content and images.
Computer vision: Identify objects in an object or video.
Audio generation: Use synthesized voices to interact with customers.
Classification: Label the severity of a customer-reported issue.
Task automation: Automatically perform the next step in a workflow as tasks are
completed.
ノ Expand table
Scenario Tutorial
Summarize text Summarize text using Azure AI chat app with .NET
Chat with your data Get insight about your data from an .NET Azure AI chat app
Call .NET functions with AI Extend Azure AI using tools and execute a local function with .NET
Browse the table of contents to learn more about the core concepts, starting with How
generative AI and LLMs work.
Next steps
Quickstart: Build an Azure AI chat app with .NET
Video series: Machine Learning and AI with .NET
Azure SDK for .NET overview
Article • 04/25/2025
The Azure SDK for .NET is a collection of NuGet packages that can be used in applications
targeting .NET variants that implement .NET Standard 2.0.
1. Locate the appropriate SDK package - Use the package list to find the appropriate
package for the Azure service you are working with. Be advised that most services have a
client package for working with the service and a management package for creating and
managing instances of the service. In most cases, you will want the client package. Install
this package in your application using NuGet.
2. Set up authentication for your application - To access Azure resources, your application
will need to have the appropriate credentials and access rights assigned in Azure. Learn
how to configure authentication in Authenticating .NET applications to Azure.
3. Write code using the SDK in your application - When working with Azure services, your
code will first create a client object to work with the service and then call methods on that
client object to interact with the service. Both synchronous and asynchronous methods
are provided. Examples of using each individual SDK package are provided throughout
the Azure documentation.
4. Configure logging for the SDK (optional) - If you need to diagnose issues between your
application and Azure, you can enable logging in the Azure SDK for .NET.
Authenticate .NET apps to Azure
services using the Azure Identity library
Article • 02/20/2025
Apps can use the Azure Identity library to authenticate to Microsoft Entra ID, which
allows the apps to access Azure services and resources. This authentication requirement
applies whether the app is deployed to Azure, hosted on-premises, or running locally on
a developer workstation. The sections ahead describe the recommended approaches to
authenticate an app to Microsoft Entra ID across different environments when using the
Azure SDK client libraries.
Token-based authentication ensures only the specific apps intended to access the
Azure resource are able to do so, whereas anyone or any app with a connection
string can connect to an Azure resource.
Token-based authentication allows you to further limit Azure resource access to
only the specific permissions needed by the app. This follows the principle of least
privilege . In contrast, a connection string grants full rights to the Azure resource.
When using a managed identity for token-based authentication, Azure handles
administrative functions for you, so you don't have to worry about tasks like
securing or rotating secrets. This makes the app more secure because there's no
connection string or application secret that can be compromised.
The Azure Identity library acquires and manages Microsoft Entra tokens for you.
You can use your own Azure credentials to authenticate to Azure resources during local
development. This is typically done using a development tool, such as Azure CLI or
Visual Studio, which can provide your app with the necessary tokens to access Azure
services. This method is convenient but should only be used for development purposes.
How to use Microsoft Entra groups to efficiently manage permissions for multiple
developer accounts
How to assign roles to developer accounts to scope permissions
How to sign-in to supported local development tools
How to authenticate using a developer account from your app code
For an app to authenticate to Azure during local development using the developer's
Azure credentials, the developer must be signed-in to Azure from one of the following
developer tools:
Azure CLI
Azure Developer CLI
Azure PowerShell
Visual Studio
The Azure Identity library can detect that the developer is signed-in from one of these
tools. The library can then obtain the Microsoft Entra access token via the tool to
authenticate the app to Azure as the signed-in user.
This approach takes advantage of the developer's existing Azure accounts to streamline
the authentication process. However, a developer's account likely has more permissions
than required by the app, therefore exceeding the permissions the app runs with in
production. As an alternative, you can create application service principals to use during
local development, which can be scoped to have only the access needed by the app.
Every developer has the same roles assigned at the group level.
If a new role is needed for the app, it only needs to be added to the group for the
app.
If a new developer joins the team, a new application service principal is created for
the developer and added to the group, ensuring the developer has the right
permissions to work on the app.
Azure portal
4. On the New group page, fill out the following form fields:
6. In the flyout panel that opens, search for the service principal you created
earlier and select it from the filtered results. Choose the Select button at the
bottom of the panel to confirm your selection.
7. Select Create at the bottom of the New group page to create the group and
return to the All groups page. If you don't see the new group listed, wait a
moment and refresh the page.
Azure portal
1. In the Azure portal, navigate to the Overview page of the resource group that
contains your app.
4. On the Role tab, use the search box to locate the role you want to assign.
Select the role, and then choose Next.
For the Assign access to value, select User, group, or service principal .
For the Members value, choose + Select members to open the Select
members flyout panel.
Search for the Microsoft Entra group you created earlier and select it
from the filtered results. Choose Select to select the group and close the
flyout panel.
Select Review + assign at the bottom of the Members tab.
6. On the Review + assign tab, select Review + assign at the bottom of the
page.
Visual Studio
Developers using Visual Studio 2017 or later can authenticate using their developer
account through the IDE. Apps using DefaultAzureCredential or
VisualStudioCredential can discover and use this account to authenticate app
requests when running locally. This account is also used when you publish apps
directly from Visual Studio to Azure.
) Important
You'll need to install the Azure development workload to enable Visual Studio
tooling for Azure authentication, development, and deployment.
1. Inside Visual Studio, navigate to Tools > Options to open the options dialog.
2. In the Search Options box at the top, type Azure to filter the available options.
4. Select the drop-down menu under Choose an account and choose to add a
Microsoft account.
5. In the window that opens, enter the credentials for your desired Azure
account, and then confirm your inputs.
credential fails to acquire an access token, the next credential in the sequence is
attempted, and so on, until an access token is successfully obtained. In this way, your
app can use different credentials in different environments without writing environment-
specific code.
Command Line
In a terminal of your choice, navigate to the application project directory and run
the following commands:
.NET CLI
Azure services are accessed using specialized client classes from the various Azure SDK
client libraries. These classes and your own custom services should be registered so they
can be accessed via dependency injection throughout your app. In Program.cs ,
complete the following steps to register a client class and DefaultAzureCredential :
2. Register the Azure service client using the corresponding Add -prefixed extension
method.
3. Pass an instance of DefaultAzureCredential to the UseCredential method.
C#
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddBlobServiceClient(
new Uri("https://<account-name>.blob.core.windows.net"));
clientBuilder.UseCredential(new DefaultAzureCredential());
});
C#
builder.Services.AddSingleton<BlobServiceClient>(_ =>
new BlobServiceClient(
new Uri("https://<account-name>.blob.core.windows.net"),
new DefaultAzureCredential()));
Authenticate .NET apps to Azure
services during local development using
service principals
Article • 03/12/2025
Using dedicated application service principals allows you to adhere to the principle of
least privilege when accessing Azure resources. Permissions are limited to the specific
requirements of the app during development, preventing accidental access to Azure
resources intended for other apps or services. This approach also helps avoid issues
when the app is moved to production by ensuring it isn't over-privileged in the
development environment.
When the app is registered in Azure, an application service principal is created. For local
development:
Create a separate app registration for each developer working on the app to
ensure each developer has their own application service principal, avoiding the
need to share credentials.
Create a separate app registration for each app to limit the app's permissions to
only what is necessary.
During local development, environment variables are set with the application service
principal's identity. The Azure Identity library reads these environment variables to
authenticate the app to the required Azure resources.
Azure portal
1. In the Azure portal, use the search bar to navigate to the App registrations
page.
For the Name field, enter a descriptive value that includes the app name
and the target environment.
For the Supported account types, select Accounts in this organizational
directory only (Microsoft Customer Led only - Single tenant), or
whichever option best fits your requirements.
4. Select Register to register your app and create the service principal.
5. On the App registration page for your app, copy the Application (client) ID
and Directory (tenant) ID and paste them in a temporary location for later use
in your app code configurations.
9. On the Certificates & secrets page, copy the Value property of the client
secret for use in a future step.
7 Note
The client secret value is only displayed once after the app registration is
created. You can add more client secrets without invalidating this client
secret, but there's no way to display this value again.
Create a Microsoft Entra group for local
development
Create a Microsoft Entra group to encapsulate the roles (permissions) the app needs in
local development rather than assigning the roles to individual service principal objects.
This approach offers the following advantages:
Every developer has the same roles assigned at the group level.
If a new role is needed for the app, it only needs to be added to the group for the
app.
If a new developer joins the team, a new application service principal is created for
the developer and added to the group, ensuring the developer has the right
permissions to work on the app.
Azure portal
4. On the New group page, fill out the following form fields:
6. In the flyout panel that opens, search for the service principal you created
earlier and select it from the filtered results. Choose the Select button at the
bottom of the panel to confirm your selection.
7. Select Create at the bottom of the New group page to create the group and
return to the All groups page. If you don't see the new group listed, wait a
moment and refresh the page.
Azure portal
1. In the Azure portal, navigate to the Overview page of the resource group that
contains your app.
4. On the Role tab, use the search box to locate the role you want to assign.
Select the role, and then choose Next.
For the Assign access to value, select User, group, or service principal .
For the Members value, choose + Select members to open the Select
members flyout panel.
Search for the Microsoft Entra group you created earlier and select it
from the filtered results. Choose Select to select the group and close the
flyout panel.
Select Review + assign at the bottom of the Members tab.
6. On the Review + assign tab, select Review + assign at the bottom of the
page.
for service principal information by convention in the environment variables. There are
multiple ways to configure environment variables when working with .NET, depending
on your tooling and environment.
Regardless of the approach you choose, configure the following environment variables
for a service principal:
AZURE_CLIENT_SECRET : The secret credential that was generated for the app.
Windows
You can set environment variables for Windows from the command line. However,
the values are accessible to all apps running on that operating system and could
cause conflicts, so use caution with this approach. Environment variables can be set
at the user or system level.
Bash
PowerShell can also be used to set environment variables at the user or system
level:
PowerShell
Command Line
In a terminal of your choice, navigate to the application project directory and run
the following commands:
.NET CLI
Azure services are accessed using specialized client classes from the various Azure SDK
client libraries. These classes and your own custom services should be registered for
dependency injection so they can be used throughout your app. In Program.cs ,
complete the following steps to configure a client class for dependency injection and
token-based authentication:
2. Register the Azure service client using the corresponding Add -prefixed extension
method.
3. Configure ClientSecretCredential with the tenantId , clientId , and clientSecret .
4. Pass the ClientSecretCredential instance to the UseCredential method.
C#
builder.Services.AddAzureClients(clientBuilder =>
{
var tenantId = Environment.GetEnvironmentVariable("AZURE_TENANT_ID");
var clientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID");
var clientSecret =
Environment.GetEnvironmentVariable("AZURE_CLIENT_SECRET");
clientBuilder.AddBlobServiceClient(
new Uri("https://<account-name>.blob.core.windows.net"));
clientBuilder.UseCredential(new ClientSecretCredential(tenantId,
clientId, clientSecret));
});
C#
builder.Services.AddSingleton<BlobServiceClient>(_ =>
new BlobServiceClient(
new Uri("https://<account-name>.blob.core.windows.net"),
new ClientSecretCredential(tenantId, clientId, clientSecret)));
Authenticate Azure-hosted .NET apps to
Azure resources using a system-
assigned managed identity
Article • 02/20/2025
There are two types of managed identities to consider when configuring your hosted
app:
The sections ahead describe the steps to enable and use a system-assigned managed
identity for an Azure-hosted app. If you need to use a user-assigned managed identity,
visit the user-assigned managed identities article for more information.
You can enable a system-assigned managed identity for an Azure resource using either
the Azure portal or the Azure CLI.
Azure portal
1. In the Azure portal, navigate to the resource that hosts your application code,
such as an Azure App Service or Azure Container App instance.
2. From the resource's Overview page, expand Settings and select Identity from
the navigation.
The following example shows how to assign roles at the resource group scope, since
many apps manage all their related Azure resources using a single resource group.
Azure portal
1. Navigate to the Overview page of the resource group that contains the app
with the system-assigned managed identity.
3. On the Access control (IAM) page, select + Add on the top menu and then
choose Add role assignment to navigate to the Add role assignment page.
4. The Add role assignment page presents a tabbed, multi-step workflow to
assign roles to identities. On the initial Role tab, use the search box at the top
to locate the role you want to assign to the identity.
5. Select the role from the results and then choose Next to move to the
Members tab.
7. For the Members option, choose + Select members to open the Select
managed identities panel.
8. On the Select managed identities panel, use the Subscription and Managed
identity dropdowns to filter the search results for your identities. Use the
Select search box to locate the system-identity you enabled for the Azure
resource hosting your app.
9. Select the identity and choose Select at the bottom of the panel to continue.
11. On the final Review + assign tab, select Review + assign to complete the
workflow.
Authenticate to Azure services from your app
The Azure Identity library provides various credentials—implementations of
TokenCredential adapted to supporting different scenarios and Microsoft Entra
authentication flows. Since managed identity is unavailable when running locally, the
steps ahead demonstrate which credential to use in which scenario:
Local dev environment: During local development only, use a class called
DefaultAzureCredential for an opinionated, preconfigured chain of credentials.
DefaultAzureCredential discovers user credentials from your local tooling or IDE,
such as the Azure CLI or Visual Studio. It also provides flexibility and convenience
for retries, wait times for responses, and support for multiple authentication
options. Visit the Authenticate to Azure services during local development article
to learn more.
Azure-hosted apps: When your app is running in Azure, use
ManagedIdentityCredential to safely discover the managed identity configured for
your app. Specifying this exact type of credential prevents other available
credentials from being picked up unexpectedly.
Command Line
In a terminal of your choice, navigate to the application project directory and run
the following commands:
.NET CLI
Azure services are accessed using specialized client classes from the various Azure SDK
client libraries. These classes and your own custom services should be registered for
dependency injection so they can be used throughout your app. In Program.cs ,
complete the following steps to configure a client class for dependency injection and
token-based authentication:
1. Include the Azure.Identity and Microsoft.Extensions.Azure namespaces via
using directives.
2. Register the Azure service client using the corresponding Add -prefixed extension
method.
3. Pass an appropriate TokenCredential instance to the UseCredential method:
C#
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddBlobServiceClient(
new Uri("https://<account-name>.blob.core.windows.net"));
if (builder.Environment.IsProduction())
{
// Managed identity token credential discovered when running in
Azure environments
credential = new ManagedIdentityCredential();
}
else
{
// Running locally on dev machine - DO NOT use in production or
outside of local dev
credential = new DefaultAzureCredential();
}
clientBuilder.UseCredential(credential);
});
C#
if (builder.Environment.IsProduction() || builder.Environment.IsStaging())
{
// Managed identity token credential discovered when running in Azure
environments
credential = new ManagedIdentityCredential();
}
else
{
// Running locally on dev machine - DO NOT use in production or outside
of local dev
credential = new DefaultAzureCredential();
}
builder.Services.AddSingleton<BlobServiceClient>(_ =>
new BlobServiceClient(
new Uri("https://<account-name>.blob.core.windows.net"),
credential));
The preceding code behaves differently depending on the environment where it's
running:
There are two types of managed identities to consider when configuring your hosted
app:
The sections ahead describe the steps to enable and use a user-assigned managed
identity for an Azure-hosted app. If you need to use a system-assigned managed
identity, visit the system-assigned managed identities article for more information.
Azure portal
1. In the Azure portal, enter Managed identities in the main search bar and select
the matching result under the Services section.
7. On the new identity's Overview page, copy the Client ID value to use for later
when you configure the application code.
Azure portal
1. In the Azure portal, navigate to the resource that hosts your app code, such as
an Azure App Service or Azure Container App instance.
2. From the resource's Overview page, expand Settings and select Identity from
the navigation.
4. Select + Add to open the Add user assigned managed identity panel.
5. On the Add user assigned managed identity panel, use the Subscription
dropdown to filter the search results for your identities. Use the User assigned
managed identities search box to locate the user-assigned managed identity
you enabled for the Azure resource hosting your app.
6. Select the identity and choose Add at the bottom of the panel to continue.
The following example shows how to assign roles at the resource group scope, since
many apps manage all their related Azure resources using a single resource group.
Azure portal
1. Navigate to the Overview page of the resource group that contains the app
with the user-assigned managed identity.
3. On the Access control (IAM) page, select + Add on the top menu and then
choose Add role assignment to navigate to the Add role assignment page.
4. The Add role assignment page presents a tabbed, multi-step workflow to
assign roles to identities. On the initial Role tab, use the search box at the top
to locate the role you want to assign to the identity.
5. Select the role from the results and then choose Next to move to the
Members tab.
7. For the Members option, choose + Select members to open the Select
managed identities panel.
8. On the Select managed identities panel, use the Subscription and Managed
identity dropdowns to filter the search results for your identities. Use the
Select search box to locate the user-assigned managed identity you enabled
for the Azure resource hosting your app.
9. Select the identity and choose Select at the bottom of the panel to continue.
11. On the final Review + assign tab, select Review + assign to complete the
workflow.
Authenticate to Azure services from your app
The Azure Identity library provides various credentials—implementations of
TokenCredential adapted to supporting different scenarios and Microsoft Entra
authentication flows. Since managed identity is unavailable when running locally, the
steps ahead demonstrate which credential to use in which scenario:
Local dev environment: During local development only, use a class called
DefaultAzureCredential for an opinionated, preconfigured chain of credentials.
DefaultAzureCredential discovers user credentials from your local tooling or IDE,
such as the Azure CLI or Visual Studio. It also provides flexibility and convenience
for retries, wait times for responses, and support for multiple authentication
options. Visit the Authenticate to Azure services during local development article
to learn more.
Azure-hosted apps: When your app is running in Azure, use
ManagedIdentityCredential to safely discover the managed identity configured for
your app. Specifying this exact type of credential prevents other available
credentials from being picked up unexpectedly.
Command Line
In a terminal of your choice, navigate to the application project directory and run
the following commands:
.NET CLI
Azure services are accessed using specialized client classes from the various Azure SDK
client libraries. These classes and your own custom services should be registered for
dependency injection so they can be used throughout your app. In Program.cs ,
complete the following steps to configure a client class for dependency injection and
token-based authentication:
1. Include the Azure.Identity and Microsoft.Extensions.Azure namespaces via
using directives.
2. Register the Azure service client using the corresponding Add -prefixed extension
method.
3. Pass an appropriate TokenCredential instance to the UseCredential method:
Client ID
Azure CLI
az identity show \
--resource-group <resource-group-name> \
--name <identity-name> \
--query 'clientId'
C#
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddBlobServiceClient(
new Uri("https://<account-name>.blob.core.windows.net"));
if (builder.Environment.IsProduction() ||
builder.Environment.IsStaging())
{
// Managed identity token credential discovered when
running in Azure environments
credential = new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId("<client-
id>"));
}
else
{
// Running locally on dev machine - DO NOT use in
production or outside of local dev
credential = new DefaultAzureCredential();
}
clientBuilder.UseCredential(credential);
});
C#
if (builder.Environment.IsProduction() ||
builder.Environment.IsStaging())
{
// Managed identity token credential discovered when running in
Azure environments
credential = new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId("<client-id>"));
}
else
{
// Running locally on dev machine - DO NOT use in production or
outside of local dev
credential = new DefaultAzureCredential();
}
builder.Services.AddSingleton<BlobServiceClient>(_ =>
new BlobServiceClient(
new Uri("https://<account-name>.blob.core.windows.net"),
credential));
The preceding code behaves differently depending on the environment where it's
running:
Using dedicated application service principals allows you to adhere to the principle of
least privilege when accessing Azure resources. Permissions are limited to the specific
requirements of the app during development, preventing accidental access to Azure
resources intended for other apps or services. This approach also helps avoid issues
when the app is moved to production by ensuring it isn't over-privileged in the
development environment.
A different app registration should be created for each environment the app is hosted
in. This allows environment specific resource permissions to be configured for each
service principal and make sure an app deployed to one environment doesn't talk to
Azure resources that are part of another environment.
Azure portal
1. In the Azure portal, use the search bar to navigate to the App registrations
page.
For the Name field, enter a descriptive value that includes the app name
and the target environment.
For the Supported account types, select Accounts in this organizational
directory only (Microsoft Customer Led only - Single tenant), or
whichever option best fits your requirements.
4. Select Register to register your app and create the service principal.
5. On the App registration page for your app, copy the Application (client) ID
and Directory (tenant) ID and paste them in a temporary location for later use
in your app code configurations.
9. On the Certificates & secrets page, copy the Value property of the client
secret for use in a future step.
7 Note
The client secret value is only displayed once after the app registration is
created. You can add more client secrets without invalidating this client
secret, but there's no way to display this value again.
Azure portal
1. In the Azure portal, navigate to the Overview page of the resource group that
contains your app.
3. On the Access control (IAM) page, select + Add and then choose Add role
assignment from the drop-down menu. The Add role assignment page
provides several tabs to configure and assign roles.
4. On the Role tab, use the search box to locate the role you want to assign.
Select the role, and then choose Next.
For the Assign access to value, select User, group, or service principal .
For the Members value, choose + Select members to open the Select
members flyout panel.
Search for the service principal you created earlier and select it from the
filtered results. Choose Select to select the group and close the flyout
panel.
Select Review + assign at the bottom of the Members tab.
6. On the Review + assign tab, select Review + assign at the bottom of the
page.
for service principal information by convention in the environment variables. There are
multiple ways to configure environment variables when working with .NET, depending
on your tooling and environment.
Regardless of the approach you choose, configure the following environment variables
for a service principal:
AZURE_CLIENT_SECRET : The secret credential that was generated for the app.
Windows
You can set environment variables for Windows from the command line. However,
the values are accessible to all apps running on that operating system and could
cause conflicts, so use caution with this approach. Environment variables can be set
at the user or system level.
Bash
# Set user environment variables
setx ASPNETCORE_ENVIRONMENT "Development"
setx AZURE_CLIENT_ID "<your-client-id>"
setx AZURE_TENANT_ID "<your-tenant-id>"
setx AZURE_CLIENT_SECRET "<your-client-secret>"
PowerShell can also be used to set environment variables at the user or system
level:
PowerShell
Command Line
In a terminal of your choice, navigate to the application project directory and run
the following commands:
.NET CLI
Azure services are accessed using specialized client classes from the various Azure SDK
client libraries. These classes and your own custom services should be registered for
dependency injection so they can be used throughout your app. In Program.cs ,
complete the following steps to configure a client class for dependency injection and
token-based authentication:
2. Register the Azure service client using the corresponding Add -prefixed extension
method.
3. Configure ClientSecretCredential with the tenantId , clientId , and clientSecret .
4. Pass the ClientSecretCredential instance to the UseCredential method.
C#
builder.Services.AddAzureClients(clientBuilder =>
{
var tenantId = Environment.GetEnvironmentVariable("AZURE_TENANT_ID");
var clientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID");
var clientSecret =
Environment.GetEnvironmentVariable("AZURE_CLIENT_SECRET");
clientBuilder.AddBlobServiceClient(
new Uri("https://<account-name>.blob.core.windows.net"));
clientBuilder.UseCredential(new ClientSecretCredential(tenantId,
clientId, clientSecret));
});
builder.Services.AddSingleton<BlobServiceClient>(_ =>
new BlobServiceClient(
new Uri("https://<account-name>.blob.core.windows.net"),
new ClientSecretCredential(tenantId, clientId, clientSecret)));
Create Azure Identity library credentials
via configuration files
Article • 03/15/2025
credential values using the IConfiguration abstraction for .NET. This approach allows
developers to explicitly set credential values across different environments through
configuration rather than through app code directly.
AzurePipelinesCredential
ClientCertificateCredential
ClientSecretCredential
DefaultAzureCredential
ManagedIdentityCredential
WorkloadIdentityCredential
C#
builder.Services.AddAzureClients(clientBuilder =>
{
// Register BlobServiceClient using credential from appsettings.json
clientBuilder.AddBlobServiceClient(builder.Configuration.GetSection("Storage
"));
JSON
"Storage": {
"serviceUri": "<service_uri>",
"credential": "managedidentity",
"clientId": "<client_id>"
}
AzurePipelinesCredential
ClientCertificateCredential
ClientSecretCredential
DefaultAzureCredential
WorkloadIdentityCredential
Add the wildcard value * to allow the credential to acquire tokens for any Microsoft
Entra tenant the logged in account can access. If no tenant IDs are specified, this option
has no effect on that authentication method, and the credential will acquire tokens for
any requested tenant when using that method.
JSON
{
"additionallyAllowedTenants": "<tenant_ids_separated_by_semicolon>"
}
Client ID
JSON
{
"credential": "managedidentity",
"clientId": "<client_id>"
}
JSON
{
"credential": "managedidentity"
}
JSON
{
"credential": "azurepipelines",
"clientId": "<client_id>",
"tenantId": "<tenant_id>",
"serviceConnectionId": "<service_connection_id>",
"systemAccessToken": "<system_access_token>"
}
) Important
AzurePipelinesCredential is supported in Microsoft.Extensions.Azure versions
JSON
{
"credential": "workloadidentity",
"tenantId": "<tenant_id>",
"clientId": "<client_id>",
"tokenFilePath": "<token_file_path>"
}
JSON
{
"tenantId": "<tenant_id>",
"clientId": "<client_id>",
"clientSecret": "<client_secret>"
}
JSON
{
"tenantId": "<tenant_id>",
"clientId": "<client_id>",
"clientCertificate": "<client_certificate>",
"clientCertificateStoreLocation": "<client_certificate_store_location>"
}
7 Note
JSON
{
"tenantId": "<tenant_id>",
"clientId": "<client_id>",
"managedIdentityResourceId": "<managed_identity_resource_id>"
}
Additional methods to authenticate to
Azure resources from .NET apps
Article • 03/15/2025
This article lists additional methods apps may use to authenticate to Azure resources.
The methods on this page are less commonly used; when possible, use one of the
methods outlined in authenticating .NET apps to Azure using the Azure SDK overview.
Interactive browser authentication enables the application for all operations allowed by
the interactive login credentials. As a result, if you're the owner or administrator of your
subscription, your code has inherent access to most resources in that subscription
without having to assign any specific permissions. For this reason, the use of interactive
browser authentication is discouraged for anything but experimentation.
1. In the Azure portal , navigate to Microsoft Entra ID and select App registrations
on the left navigation.
3. Under Advanced settings, select Yes for Allow public client flows.
) Important
You must also be the admin of your tenant to grant consent to your
application when you sign in for the first time.
C#
using Azure.Identity;
using Azure.Storage.Blobs;
namespace InteractiveBrokeredAuthSample
{
public partial class InteractiveBrowserAuth : Form
{
public InteractiveBrowserAuth()
{
InitializeComponent();
}
For more exact control, such as setting redirect URIs, you can supply specific arguments
to InteractiveBrowserCredential such as redirect_uri .
WAM enables identity providers such as Microsoft Entra ID to natively plug into the OS
and provide the service to other apps to provide a more secure login process. WAM
offers the following benefits:
Feature support: Apps can access OS-level and service-level capabilities, including
Windows Hello, conditional access policies, and FIDO keys.
Streamlined single sign-on: Apps can use the built-in account picker, allowing the
user to select an existing account instead of repeatedly entering the same
credentials.
Enhanced security: Bug fixes and enhancements ship with Windows.
Token protection: Refresh tokens are device-bound, and apps can acquire device-
bound access tokens.
Interactive brokered authentication enables the application for all operations allowed by
the interactive login credentials. Personal Microsoft accounts and work or school
accounts are supported. If a supported version of Windows is used, the default browser-
based UI is replaced with a smoother authentication experience, similar to Windows
built-in apps.
1. On the Azure portal , navigate to Microsoft Entra ID and select App registrations
on the left-hand menu.
3. Add the WAM redirect URI to your app registration via a platform configuration:
b. Under Configure platforms, select the tile for your application type (platform)
to configure its settings, such as mobile and desktop applications.
ms-appx-web://microsoft.aad.brokerplugin/{client_id}
d. Select Configure.
4. Back on the Authentication pane, under Advanced settings, select Yes for Allow
public client flows.
) Important
You must also be the admin of your tenant to grant consent to your
application when you sign in for the first time.
C#
using Azure.Identity;
using Azure.Identity.Broker;
using Azure.Storage.Blobs;
namespace InteractiveBrokeredAuthSample
{
public partial class InteractiveBrokeredAuth : Form
{
public InteractiveBrokeredAuth()
{
InitializeComponent();
}
7 Note
Visit the Parent window handles and Retrieve a window handle articles for more
information about retrieving window handles.
For the code to run successfully, your user account must be assigned an Azure role on
the storage account that allows access to blob containers such as Storage Account Data
Contributor. If an app is specified, it must have API permissions set for
user_impersonation Access Azure Storage (step 6 in the previous section). This API
permission allows the app to access Azure storage on behalf of the signed-in user after
consent is granted during sign-in.
The following screenshot shows the user sign-in experience:
The following example shows how to enable sign-in with the default system account:
C#
using Azure.Identity;
using Azure.Identity.Broker;
using Azure.Storage.Blobs;
namespace InteractiveBrokeredAuthSample
{
public partial class SilentBrokeredAuth : Form
{
public SilentBrokeredAuth()
{
InitializeComponent();
}
Once you opt in to this behavior, the credential attempts to sign in by asking the
underlying Microsoft Authentication Library (MSAL) to perform the sign-in for the
default system account. If the sign-in fails, the credential falls back to displaying the
account picker dialog, from which the user can select the appropriate account.
Device code authentication
This method interactively authenticates a user on devices with limited UI (typically
devices without a keyboard):
1. When the application attempts to authenticate, the credential prompts the user
with a URL and an authentication code.
2. The user visits the URL on a separate browser-enabled device (a computer,
smartphone, etc.) and enters the code.
3. The user follows a normal authentication process in the browser.
4. Upon successful authentication, the application is authenticated on the device.
For more information, see Microsoft identity platform and the OAuth 2.0 device
authorization grant flow.
The Azure Identity library provides credentials—public classes derived from the Azure
Core library's TokenCredential class. A credential represents a distinct authentication
flow for acquiring an access token from Microsoft Entra ID. These credentials can be
chained together to form an ordered sequence of authentication mechanisms to be
attempted.
GetToken
2
loop [Traverse
TokenCredential
collection until
AccessToken received]
Fetch token
3
GetToken
4
Result
5
AccessToken
6
C#
TokenCredential credential;
if (app.Environment.IsProduction() || app.Environment.IsStaging())
{
credential = new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId(userAssignedClientId));
}
else
{
// local development environment
credential = new VisualStudioCredential();
}
Seamless transitions: Your app can move from local development to your staging
or production environment without changing authentication code.
"Tear down" a chain: Start with a preconfigured chain and exclude what you don't
need. For this approach, see the DefaultAzureCredential overview section.
"Build up" a chain: Start with an empty chain and include only what you need. For
this approach, see the ChainedTokenCredential overview section.
DefaultAzureCredential overview
DefaultAzureCredential is an opinionated, preconfigured chain of credentials. It's
designed to support many environments, along with the most common authentication
flows and developer tools. In graphical form, the underlying chain looks like this:
CREDENTIALS
Environment Workload Identity Managed Identity Visual Studio Azure CLI Azure PowerShell Azure Developer CLI Interactive browser
CREDENTIAL TYPES
ノ Expand table
5 Azure CLI If the developer authenticated to Azure using Azure CLI's az Yes
login command, authenticate the app to Azure using that
same account.
In its simplest form, you can use the parameterless version of DefaultAzureCredential as
follows:
C#
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
Tip
The UseCredential method in the preceding code snippet is recommended for use
in ASP.NET Core apps. For more information, see Use the Azure SDK for .NET in
ASP.NET Core apps.
C#
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
clientBuilder.UseCredential(new DefaultAzureCredential(
new DefaultAzureCredentialOptions
{
ExcludeEnvironmentCredential = true,
ExcludeManagedIdentityCredential = true,
ExcludeWorkloadIdentityCredential = true,
}));
});
7 Note
As more Exclude -prefixed properties are set to true (credential exclusions are
configured), the advantages of using DefaultAzureCredential diminish. In such cases,
ChainedTokenCredential is a better choice and requires less code. To illustrate, these two
DefaultAzureCredential
C#
ChainedTokenCredential overview
ChainedTokenCredential is an empty chain to which you add credentials to suit your
app's needs. For example:
C#
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
clientBuilder.UseCredential(new ChainedTokenCredential(
new AzurePowerShellCredential(),
new VisualStudioCredential()));
});
The preceding code sample creates a tailored credential chain comprised of two
development-time credentials. AzurePowerShellCredential is attempted first, followed
by VisualStudioCredential , if necessary. In graphical form, the chain looks like this:
Tip
Identity library, but with that convenience comes tradeoffs. Once you deploy your app
to Azure, you should understand the app's authentication requirements. For that reason,
replace DefaultAzureCredential with a specific TokenCredential implementation, such
as ManagedIdentityCredential . See the Derived list for options.
Here's why:
C#
Output
in that order.
The DefaultAzureCredential credential selected: -prefixed entry indicates the
credential that was selected— VisualStudioCredential in this case. Since
VisualStudioCredential succeeded, no credentials beyond it were used.
Authentication best practices with the
Azure Identity library for .NET
Article • 02/15/2025
This article offers guidelines to help you maximize the performance and reliability of
your .NET apps when authenticating to Azure services. To make the most of the Azure
Identity library for .NET, it's important to understand potential issues and mitigation
techniques.
3. Without telling the support team, a developer installs the Azure CLI on that VM
and runs the az login command to authenticate to Azure.
4. Due to a separate configuration change in the Azure environment, authentication
via the original managed identity unexpectedly begins to fail silently.
5. DefaultAzureCredential skips the failed ManagedIdentityCredential and searches
for the next available credential, which is AzureCliCredential .
6. The application starts utilizing the Azure CLI credentials rather than the managed
identity, which may fail or result in unexpected elevation or reduction of privileges.
To prevent these types of subtle issues or silent failures in production apps, replace
DefaultAzureCredential with a specific TokenCredential implementation, such as
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
Modify the preceding code to select a credential based on the environment in which the
app is running:
C#
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
TokenCredential credential;
if (builder.Environment.IsProduction() ||
builder.Environment.IsStaging())
{
string? clientId = builder.Configuration["UserAssignedClientId"];
credential = new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId(clientId));
}
else
{
// local development environment
credential = new ChainedTokenCredential(
new VisualStudioCredential(),
new AzureCliCredential(),
new AzurePowerShellCredential());
}
clientBuilder.UseCredential(credential);
});
) Important
A high-volume app that doesn't reuse credentials may encounter HTTP 429
throttling responses from Microsoft Entra ID, which can lead to app outages.
ASP.NET Core
C#
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
new Uri($"https://{keyVaultName}.vault.azure.net"));
clientBuilder.AddBlobServiceClient(
new Uri($"https://{storageAccountName}.blob.core.windows.net"));
TokenCredential credential;
if (builder.Environment.IsProduction() ||
builder.Environment.IsStaging())
{
string? clientId =
builder.Configuration["UserAssignedClientId"];
credential = new ManagedIdentityCredential(
ManagedIdentityId.FromUserAssignedClientId(clientId));
}
else
{
// local development environment
credential = new ChainedTokenCredential(
new VisualStudioCredential(),
new AzureCliCredential(),
new AzurePowerShellCredential());
}
clientBuilder.UseCredential(credential);
});
For information on this approach in an ASP.NET Core app, see Authenticate using
Microsoft Entra ID.
To only call GetToken when necessary, observe the RefreshOn date and proactively
attempt to refresh the token after that time. The specific implementation is up to the
customer.
acquisition attempt fails or times out after a short duration. This is the least
resilient option because it's optimized to "fail fast" for an efficient development
inner loop.
Any other approach, such as ChainedTokenCredential or
ManagedIdentityCredential directly:
The time interval between retries starts at 0.8 seconds, and a maximum of five
retries are attempted, by default. This option is optimized for resilience but
introduces potentially unwanted delays in the development inner loop.
To change any of the default retry settings, use the Retry property on
ManagedIdentityCredentialOptions . For example, retry a maximum of three
C#
For more information on customizing retry policies, see Setting a custom retry policy .
Use the Azure SDK for .NET in ASP.NET
Core apps
Article • 11/16/2024
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 adopt the Azure
SDK for .NET in your ASP.NET Core apps. You'll learn how to:
In the sections ahead, you'll explore how to implement an ASP.NET Core application that
uses these libraries.
.NET CLI
.NET CLI
3. In the Program.cs file of your app, invoke the AddAzureClients extension method
from the Microsoft.Extensions.Azure library to register a client to communicate
with each Azure service. Some client libraries provide additional subclients for
specific subgroups of Azure service functionality. You can register such subclients
for dependency injection via the AddClient extension method.
C#
builder.Services.AddAzureClients(clientBuilder =>
{
// Register a client for each Azure service using inline
configuration
clientBuilder.AddSecretClient(new Uri("<key_vault_url>"));
clientBuilder.AddBlobServiceClient(new Uri("<storage_url>"));
clientBuilder.AddServiceBusClientWithNamespace(
"<your_namespace>.servicebus.windows.net");
4. Inject the registered clients into your ASP.NET Core app components, services, or
API endpoint:
Minimal API
C#
app.MapGet("/reports", async (
BlobServiceClient blobServiceClient,
IAzureClientFactory<ServiceBusSender> senderFactory) =>
{
// Create the named client
ServiceBusSender serviceBusSender =
senderFactory.CreateClient("queue1");
await serviceBusSender.SendMessageAsync(new
ServiceBusMessage("Hello world"));
return reports;
})
.WithName("GetReports");
For more information, see Dependency injection with the Azure SDK for .NET.
7 Note
Many Azure services also allow you to authorize requests using 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 can
authorize requests against the associated Azure resource.
.NET CLI
2. In the Program.cs file of your app, invoke the UseCredential extension method
from the Microsoft.Extensions.Azure library to set a shared
DefaultAzureCredential instance for all registered Azure service clients:
C#
builder.Services.AddAzureClients(clientBuilder =>
{
// Register a client for each Azure service using inline
configuration
clientBuilder.AddSecretClient(new Uri("<key_vault_url>"));
clientBuilder.AddBlobServiceClient(new Uri("<storage_url>"));
clientBuilder.AddServiceBusClientWithNamespace(
"<your_namespace>.servicebus.windows.net");
and uses them to authenticate to Azure services. For the order and locations in
which DefaultAzureCredential scans for credentials, see DefaultAzureCredential
overview. Using a shared DefaultAzureCredential instance ensures the underlying
token cache is used, which improves application resilience and performance due to
fewer requests for a new token.
Apply configurations
Azure SDK service clients support configurations to change their default behaviors.
There are two ways to configure service clients:
JSON configuration files are generally the recommended approach because they
simplify managing differences in app deployments between environments.
Inline code configurations can be applied when you register the service client. For
example, in the Register clients and subclients section, you explicitly passed the
URI variables to the client constructors.
Complete the steps in the following sections to update your app to use JSON file
configuration for the appropriate environments. Use the appsettings.Development.json
file for development settings and the appsettings.Production.json file for production
environment settings. You can add configuration settings whose names are public
properties on the ClientOptions class to the JSON file.
JSON
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Azure.Messaging.ServiceBus": "Debug"
}
},
"AzureDefaults": {
"Diagnostics": {
"IsTelemetryDisabled": false,
"IsLoggingContentEnabled": true
},
"Retry": {
"MaxRetries": 3,
"Mode": "Exponential"
}
},
"KeyVault": {
"VaultUri": "https://<your-key-vault-name>.vault.azure.net"
},
"ServiceBus": {
"Namespace": "<your_service-bus_namespace>.servicebus.windows.net"
},
"Storage": {
"ServiceUri": "https://<your-storage-account-
name>.storage.windows.net"
}
}
The top-level key names, KeyVault , ServiceBus , and Storage , are arbitrary
names used to reference the config sections from your code. You will pass
these names to AddClient extension methods to configure a given client. All
other key names map to specific client options, and JSON serialization is
performed in a case-insensitive manner.
The KeyVault:VaultUri , ServiceBus:Namespace , and Storage:ServiceUri key
values map to the arguments of the SecretClient(Uri, TokenCredential,
SecretClientOptions), ServiceBusClient(String), and BlobServiceClient(Uri,
TokenCredential, BlobClientOptions) constructor overloads, respectively. The
TokenCredential variants of the constructors are used because a default
2. Update the the Program.cs file to retrieve the JSON file configurations using
IConfiguration and pass them into your service registrations:
C#
builder.Services.AddAzureClients(clientBuilder =>
{
// Register clients using a config file section
clientBuilder.AddSecretClient(
builder.Configuration.GetSection("KeyVault"));
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("Storage"));
1. Update your configuration file to set default Azure settings, such as a new default
retry policy that all registered Azure clients will use:
JSON
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Azure.Messaging.ServiceBus": "Debug"
}
},
"AzureDefaults": {
"Diagnostics": {
"IsTelemetryDisabled": false,
"IsLoggingContentEnabled": true
},
"Retry": {
"MaxRetries": 3,
"Mode": "Exponential"
}
},
"KeyVault": {
"VaultUri": "https://<your-key-vault-name>.vault.azure.net"
},
"ServiceBus": {
"Namespace": "<your_service-bus_namespace>.servicebus.windows.net"
},
"Storage": {
"ServiceUri": "https://<your-storage-account-
name>.storage.windows.net"
}
}
2. In the Program.cs file, call the ConfigureDefaults extension method to retrieve the
default settings and apply them to your service clients:
C#
builder.Services.AddAzureClients(clientBuilder =>
{
// Register clients using a config file section
clientBuilder.AddSecretClient(
builder.Configuration.GetSection("KeyVault"));
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("Storage"));
clientBuilder.UseCredential(new DefaultAzureCredential());
Configure logging
The Azure SDK for .NET client libraries can log client library operations to monitor
requests and responses to Azure services. Client libraries can also log a variety of other
events, including retries, token retrieval, and service-specific events from various clients.
When you register an Azure SDK client using the AddAzureClients extension method,
the AzureEventSourceLogForwarder is registered with the dependency injection
container. The AzureEventSourceLogForwarder forwards log messages from Azure SDK
event sources to ILoggerFactory to enables you to use the standard ASP.NET Core
logging configuration for logging.
The following table depicts how the Azure SDK for .NET EventLevel maps to the
ASP.NET Core LogLevel . For more information on these topics and other scenarios, see
Logging with the Azure SDK for .NET and Dependency injection with the Azure SDK for
.NET.
ノ Expand table
Critical Critical
Error Error
Informational Information
Warning Warning
Verbose Debug
LogAlways Information
You can change default log levels and other settings using the same JSON
configurations outlined in the configure authentication section. For example, toggle the
ServiceBusClient log level to Debug by setting the
JSON
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Azure.Messaging.ServiceBus": "Debug"
}
},
"AzureDefaults": {
"Diagnostics": {
"IsTelemetryDisabled": false,
"IsLoggingContentEnabled": true
},
"Retry": {
"MaxRetries": 3,
"Mode": "Exponential"
}
},
"KeyVault": {
"VaultUri": "https://<your-key-vault-name>.vault.azure.net"
},
"ServiceBus": {
"Namespace": "<your_service-bus_namespace>.servicebus.windows.net"
},
"Storage": {
"ServiceUri": "https://<your-storage-account-name>.storage.windows.net"
}
}
Resource management using the Azure
SDK for .NET
Article • 04/25/2025
The Azure SDK for .NET management plane libraries will help you create, provision, and
manage Azure resources from within .NET applications. All Azure services have corresponding
management libraries.
Those packages follow the new Azure SDK guidelines , which provide core capabilities that
are shared amongst all Azure SDKs, including:
7 Note
You might notice that some packages are still prerelease version. Phased releases of
additional Azure services' management plane libraries are in process. If you're looking for
a stable version package for a particular Azure resource and currently only a prerelease
version is available, please raise an issue in Azure SDK for .NET GitHub repo .
Get started
Prerequisites
An Azure subscription .
A TokenCredential implementation, such as an Azure Identity library credential type.
PowerShell
Install-Package Azure.Identity
Install-Package Azure.ResourceManager
Install-Package Azure.ResourceManager.Resources
Install-Package Azure.ResourceManager.Compute
Install-Package Azure.ResourceManager.Network
To authenticate with Azure and create an ArmClient , instantiate an ArmClient given credentials:
C#
using Azure.Identity;
using Azure.ResourceManager;
using System;
using System.Threading.Tasks;
1. Authenticate to the subscription and resource group that you want to work on.
C#
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.ServiceBus;
ArmClient client = new ArmClient(new DefaultAzureCredential());
SubscriptionResource subscription = client.GetDefaultSubscription();
ResourceGroupResource resourceGroup =
client.GetDefaultSubscription().GetResourceGroup(resourceGroupName);
ノ Expand table
Operation Method
List resourceGroup.GetServiceBusNamespaces()
Remember, all the Azure resources, including the resource group itself, can be managed by
their corresponding management SDK using code similar to the above example. To find the
correct Azure management SDK package, look for packages named with the following pattern
Azure.ResourceManager.{ResourceProviderName} .
To learn more about the ResourceIdentifier, please refer to Structured Resource Identifier.
Key concepts
{ResourceName}Resource class
This type represents a full resource client object that contains a Data property exposing the
details as a {ResourceName}Data type. It also has access to all of the operations on that
resource without needing to pass in scope parameters such as subscription ID or resource
name. This makes it convenient to directly execute operations on the result of list calls, since
everything is returned as a full resource client now.
C#
{ResourceName}Data class
This type represents the model that makes up a given resource. Typically, this is the response
data from a service call such as HTTP GET and provides details about the underlying resource.
Previously, this was represented by a Model class.
{ResourceName}Collection class
This type represents the operations you can perform on a collection of resources belonging to
a specific parent resource. This object provides most of the logical collection operations.
ノ Expand table
Iterate/List GetAll()
Collection Collection Method
Behavior
In most cases, parent of a resource is ResourceGroup, but in some cases, a resource itself has
sub resource, for example a Subnet is a child of a VirtualNetwork. ResourceGroup itself is a
child of a Subscription
C#
C#
However, keep in mind that some of those properties could be null. You can usually tell by the
ID string itself which type a resource ID is. But if you're unsure, check if the properties are null.
You may not want to manually create the resourceId from a pure string . Each
{ResourceName}Resource class has a static method that can help you create the resource
identifier string.
C#
ResourceIdentifier resourceId =
AvailabilitySetResource.CreateResourceIdentifier(
"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"resourceGroupName",
"resourceName");
Performing operations on resources that already exist is a common use case when using the
management client libraries. In this scenario, you usually have the identifier of the resource you
want to work on as a string. Although the new object hierarchy is great for provisioning and
working within the scope of a given parent, it is not the most efficient when it comes to this
specific scenario.
Here's an example how you can access an AvailabilitySetResource object and manage it
directly with its resource identifier:
C#
using Azure.Identity;
using Azure.ResourceManager;
using Azure.ResourceManager.Resources;
using Azure.ResourceManager.Compute;
using System;
using System.Threading.Tasks;
ResourceIdentifier subscriptionId =
SubscriptionResource.CreateResourceIdentifier("aaaaaaaa-bbbb-cccc-dddd-
eeeeeeeeeeee");
ResourceIdentifier resourceId =
AvailabilitySetResource.CreateResourceIdentifier(
subscriptionId.SubscriptionId,
"resourceGroupName",
"resourceName");
This approach required a lot of code and three API calls are made to Azure. The same can be
done with less code and without any API calls by using extension methods that we've provided
on the client itself. These extension methods allow you to pass in a resource identifier and
retrieve a scoped resource client. The object returned is a {ResourceName}Resource. Since it
hasn't reached out to Azure to retrieve the data yet, calling the Data property will throw
exception, you can either use HasData property to tell if the resource instance contains a data
or call the Get or GetAsync method on the resource to retrieve the resource data.
C#
ResourceIdentifier resourceId =
AvailabilitySetResource.CreateResourceIdentifier(
"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"resourceGroupName",
"resourceName");
// We construct a new armClient to work with
ArmClient client = new ArmClient(new DefaultAzureCredential());
// Next we get the AvailabilitySet resource client from the armClient
// The method takes in a ResourceIdentifier but we can use the implicit cast from
string
AvailabilitySetResource availabilitySet =
client.GetAvailabilitySetResource(resourceId);
// At this point availabilitySet.Data will be null and trying to access it will
throw exception
// If we want to retrieve the objects data we can simply call get
availabilitySet = await availabilitySet.GetAsync();
// we now have the data representing the availabilitySet
Console.WriteLine(availabilitySet.Data.Name);
Task<Response<bool>> . In the Response<bool> object, you can visit its Value property to check if
a resource exists. The Value is false if the resource does not exist and vice versa.
In previous versions of packages, you would have to catch the RequestFailedException and
inspect the status code for 404. With this new API, we hope that this can boost the developer
productivity and optimize resource access.
C#
try
{
ResourceGroupResource resourceGroup = await
subscription.GetResourceGroupAsync(resourceGroupName);
// At this point, we are sure that myRG is a not null Resource Group, so we
can use this object to perform any operations we want.
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
Console.WriteLine($"Resource Group {resourceGroupName} does not exist.");
}
C#
if (exists)
{
Console.WriteLine($"Resource Group {resourceGroupName} exists.");
Examples
// With the collection, we can create a new resource group with an specific name
string resourceGroupName = "myRgName";
AzureLocation location = AzureLocation.WestUS2;
ResourceGroupData resourceGroupData = new ResourceGroupData(location);
ResourceGroupResource resourceGroup = (await
resourceGroupCollection.CreateOrUpdateAsync(resourceGroupName,
resourceGroupData)).Value;
// Note: Resource group named 'myRgName' should exist for this example to work.
ArmClient client = new ArmClient(new DefaultAzureCredential());
SubscriptionResource subscription = await client.GetDefaultSubscriptionAsync();
string resourceGroupName = "myRgName";
ResourceGroupResource resourceGroup = await
subscription.GetResourceGroupAsync(resourceGroupName);
resourceGroup = await resourceGroup.AddTagAsync("key", "value");
Next steps
Additional Documentation
If you're migrating from the old SDK to this preview, check out this Migration guide .
This article demonstrates how to register Azure service clients from the latest Azure client
libraries for .NET for dependency injection in a .NET app. Every modern .NET app starts up by
using the instructions provided in a Program.cs file.
Install packages
To register and configure service clients from an Azure.-prefixed package:
.NET CLI
.NET CLI
For demonstration purposes, the sample code in this article uses the Key Vault Secrets, Blob
Storage, Service Bus, and Azure OpenAI libraries. Install the following packages to follow along:
.NET CLI
consuming messages.
In the Program.cs file, invoke the AddAzureClients extension method to register a client for
each service. The following code samples provide guidance on application builders from the
Microsoft.AspNetCore.Builder and Microsoft.Extensions.Hosting namespaces.
WebApplicationBuilder
C#
using Azure.Identity;
using Azure.Messaging.ServiceBus;
using Azure.Messaging.ServiceBus.Administration;
using Microsoft.Extensions.Azure;
using Azure.AI.OpenAI;
return queueNames;
}
Key Vault Secrets, Blob Storage, and Service Bus clients are registered using the
AddSecretClient, AddBlobServiceClient and AddServiceBusClientWithNamespace,
respectively. The Uri - and string -typed arguments are passed. To avoid specifying these
URLs explicitly, see the Store configuration separately from code section.
DefaultAzureCredential is used to satisfy the TokenCredential argument requirement for
each registered client. When one of the clients is created, DefaultAzureCredential is used
to authenticate.
Service Bus subclients are registered for each queue on the service using the subclient
and corresponding options types. The queue names for the subclients are retrieved using
a separate method outside of the service registration because the GetQueuesAsync
method must be run asynchronously.
An Azure OpenAI client is registered using a custom client factory via the AddClient
method, which provides control over how a client instance is created. Custom client
factories are useful in the following cases:
You need to use other dependencies during the client construction.
A registration extension method doesn't exist for the service client you want to
register.
C#
[ApiController]
[Route("[controller]")]
public class MyApiController : ControllerBase
{
private readonly BlobServiceClient _blobServiceClient;
private readonly ServiceBusSender _serviceBusSender;
public MyApiController(
BlobServiceClient blobServiceClient,
IAzureClientFactory<ServiceBusSender> senderFactory)
{
_blobServiceClient = blobServiceClient;
_serviceBusSender = senderFactory.CreateClient("myQueueName");
}
[HttpGet]
public async Task<IEnumerable<string>> Get()
{
BlobContainerClient containerClient =
_blobServiceClient.GetBlobContainerClient("demo");
var results = new List<string>();
return results.ToArray();
}
}
JSON
{
"AzureDefaults": {
"Diagnostics": {
"IsTelemetryDisabled": false,
"IsLoggingContentEnabled": true
},
"Retry": {
"MaxRetries": 3,
"Mode": "Exponential"
}
},
"KeyVault": {
"VaultUri": "https://mykeyvault.vault.azure.net"
},
"ServiceBus": {
"Namespace": "<your_namespace>.servicebus.windows.net"
},
"Storage": {
"ServiceUri": "https://mydemoaccount.storage.windows.net"
}
}
You can add any properties from the ClientOptions class into the JSON file. The settings in the
JSON configuration file can be retrieved using IConfiguration.
WebApplicationBuilder
C#
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddSecretClient(
builder.Configuration.GetSection("KeyVault"));
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("Storage"));
clientBuilder.AddServiceBusClientWithNamespace(
builder.Configuration["ServiceBus:Namespace"]);
clientBuilder.UseCredential(new DefaultAzureCredential());
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.
The AzureDefaults.Retry object literal:
Represents the retry policy configuration settings.
Corresponds to the Retry property. Within that object literal, you find the MaxRetries
key, which corresponds to the MaxRetries property.
The KeyVault:VaultUri , ServiceBus:Namespace , and Storage:ServiceUri key values map
to the Uri - and string -typed arguments of the
Azure.Security.KeyVault.Secrets.SecretClient.SecretClient(Uri, TokenCredential,
SecretClientOptions),
Azure.Messaging.ServiceBus.ServiceBusClient.ServiceBusClient(String), and
Azure.Storage.Blobs.BlobServiceClient.BlobServiceClient(Uri, TokenCredential,
BlobClientOptions) constructor overloads, respectively. The TokenCredential variants of
the constructors are used because a default TokenCredential is set via the
Microsoft.Extensions.Azure.AzureClientFactoryBuilder.UseCredential(TokenCredential)
method call.
C#
builder.Services.AddAzureClients(clientBuilder =>
{
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("PublicStorage"));
clientBuilder.AddBlobServiceClient(
builder.Configuration.GetSection("PrivateStorage"))
.WithName("PrivateStorage");
});
Using an ASP.NET Core controller as an example, access the named service client using the
IAzureClientFactory<TClient> interface:
C#
public HomeController(
BlobServiceClient defaultClient,
IAzureClientFactory<BlobServiceClient> clientFactory)
{
_publicStorage = defaultClient;
_privateStorage = clientFactory.CreateClient("PrivateStorage");
}
}
The unnamed service client is still available in the same way as before. Named clients are
additive.
JSON
{
"AzureDefaults": {
"Retry": {
"maxRetries": 3
}
},
"KeyVault": {
"VaultUri": "https://mykeyvault.vault.azure.net"
},
"ServiceBus": {
"Namespace": "<your_namespace>.servicebus.windows.net"
},
"Storage": {
"ServiceUri": "https://store1.storage.windows.net"
},
"CustomStorage": {
"ServiceUri": "https://store2.storage.windows.net"
}
}
You can change the retry policy to suit your needs like so:
C#
builder.Services.AddAzureClients(clientBuilder =>
{
// Establish the global defaults
clientBuilder.ConfigureDefaults(
builder.Configuration.GetSection("AzureDefaults"));
clientBuilder.UseCredential(new DefaultAzureCredential());
clientBuilder.AddServiceBusClientWithNamespace(
builder.Configuration["ServiceBus:Namespace"])
.ConfigureOptions(options => options.RetryOptions.MaxRetries = 10);
You can also place retry policy overrides in the appsettings.json file:
JSON
{
"KeyVault": {
"VaultUri": "https://mykeyvault.vault.azure.net",
"Retry": {
"maxRetries": 10
}
}
}
See also
Dependency injection in ASP.NET Core
Configuration in .NET
Configuration in ASP.NET Core
Thread safety and client lifetime
management for Azure SDK objects
Article • 04/25/2025
This article helps you understand thread safety issues when using the Azure SDK. It also
discusses how the design of the SDK impacts client lifetime management. You'll learn why it's
unnecessary to dispose of Azure SDK client objects.
Thread safety
All Azure SDK client objects are thread-safe and independent of each other. This design
ensures that reusing client instances is always safe, even across threads. For example, the
following code launches multiple tasks but is thread safe:
C#
Model objects used by SDK clients, whether input or output models, aren't thread-safe by
default. Most use cases involving model objects only use a single thread. Therefore, the cost of
implementing synchronization as a default behavior is too high for these objects. The following
code illustrates a bug in which accessing a model from multiple threads could cause an
undefined behavior:
C#
client.UpdateSecretProperties(newSecret.Properties);
To access the model from different threads, you must implement your own synchronization
code. For example:
C#
client.UpdateSecretProperties(newSecret.Properties);
Client lifetime
Because Azure SDK clients are thread-safe, there's no reason to construct multiple SDK client
objects for a given set of constructor parameters. Treat Azure SDK client objects as singletons
once constructed. This recommendation is commonly implemented by registering Azure SDK
client objects as singletons in the app's Inversion of Control (IoC) container. Dependency
injection (DI) is used to obtain references to the SDK client object. The following example
shows a singleton client object registration:
C#
builder.Services.AddSingleton(blobServiceClient);
For more information about implementing DI with the Azure SDK, see Dependency injection
with the Azure SDK for .NET.
Alternatively, you may create an SDK client instance and provide it to methods that require a
client. The point is to avoid unnecessary instantiations of the same SDK client object with the
same parameters. It's both unnecessary and wasteful.
Do I need to dispose of Azure SDK client objects when I'm finished using them?
Why aren't HTTP-based Azure SDK client objects disposable?
Internally, all Azure SDK clients use a single shared HttpClient instance. The clients don't
create any other resources that need to be actively freed. The shared HttpClient instance
persists throughout the entire application lifetime.
C#
// Both clients reuse the shared HttpClient and don't need to be disposed
var blobClient = new BlobClient(new Uri(sasUri));
var blobClient2 = new BlobClient(new Uri(sasUri2));
It's possible to provide a custom instance of HttpClient to an Azure SDK client object. In this
case, you become responsible for managing the HttpClient lifetime and properly disposing of
it at the right time.
C#
Further guidance for properly managing and disposing of HttpClient instances can be found
in the HttpClient documentation.
See also
Dependency injection with the Azure SDK for .NET
Dependency injection in .NET
Logging with the Azure SDK for .NET
Article • 04/05/2025
The Azure SDK for .NET's client libraries include the ability to log client library operations. This
logging allows you to monitor I/O requests and responses that client libraries are making to
Azure services. Typically, the logs are used to debug or diagnose communication issues. This
article describes the following approaches to enable logging with the Azure SDK for .NET:
) Important
This article applies to client libraries that use the most recent versions of the Azure SDK for
.NET. To see if a library is supported, see the list of Azure SDK latest releases . If your
app is using an older version of an Azure SDK client library, refer to specific instructions in
the applicable service documentation.
Log information
The SDK logs each HTTP request and response, sanitizing parameter query and header values
to remove personal data.
Unique ID
HTTP method
URI
Outgoing request headers
7 Note
Content logging is disabled by default. To enable it, see Log HTTP request and
response bodies. This capability applies only to libraries using HTTP to communicate
with an Azure service. Libraries based on alternative protocols, such as AMQP, don't
support content logging. Unsupported examples include libraries for Azure services
such as Event Hubs, Service Bus, and Web PubSub.
parameter that specifies a log level. If the parameter isn't provided, the default log level of
Informational is used.
C#
C#
The following example creates an event listener that logs to the console with a custom
message. The logs are filtered to those events emitted from the Azure Core client library with a
level of verbose. The Azure Core library uses an event source name of Azure-Core .
C#
using Azure.Core.Diagnostics;
using System.Diagnostics.Tracing;
The following table depicts how the Azure SDK for .NET EventLevel maps to the ASP.NET Core
LogLevel .
ノ Expand table
Critical Critical
Error Error
Informational Information
Warning Warning
Verbose Debug
LogAlways Information
.NET CLI
2. In Program.cs, register the Azure SDK library's client via a call to the AddAzureClients
extension method:
C#
using Azure.Identity;
using Microsoft.Extensions.Azure;
builder.Services.AddAzureClients(azureBuilder =>
{
azureBuilder.AddServiceBusClient(
builder.Configuration.GetConnectionString("ServiceBus"));
azureBuilder.UseCredential(new DefaultAzureCredential());
});
Registers the following objects with the dependency injection (DI) container:
Log forwarder service
Azure Service Bus client
Sets the default token credential to be used for all registered clients.
3. In appsettings.json, change the Service Bus library's default log level. For example, toggle
it to Debug by setting the Logging:LogLevel:Azure.Messaging.ServiceBus key as follows:
JSON
{
"ConnectionStrings": {
"ServiceBus": "<connection_string>"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Azure.Messaging.ServiceBus": "Debug"
}
},
"AllowedHosts": "*"
}
.NET CLI
C#
using Azure.Identity;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.DependencyInjection.Extensions;
builder.Services.AddDataProtection()
.PersistKeysToAzureBlobStorage("<connection_string>", "<container_name>",
"keys.xml")
.ProtectKeysWithAzureKeyVault(new Uri("<uri>"), new
DefaultAzureCredential());
3. Fetch the log forwarder service from the DI container and invoke its Start method. For
example, using constructor injection in an ASP.NET Core Razor Pages page model class:
C#
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Azure;
4. In appsettings.json, change the Azure Core library's default log level. For example, toggle it
to Debug by setting the Logging:LogLevel:Azure.Core key as follows:
JSON
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Azure.Core": "Debug"
}
},
"AllowedHosts": "*"
}
Since the Logging:LogLevel:Azure.Core key is set to Debug , Azure Core library events up
to EventLevel.Verbose will be logged.
For more information, see Logging in .NET Core and ASP.NET Core.
Logging using
Azure.Monitor.OpenTelemetry.AspNetCore
The Azure Monitor OpenTelemetry distro , starting with version 1.2.0 , supports capturing
logs coming from Azure client libraries. You can control logging using any of the configuration
options discussed in Logging in .NET Core and ASP.NET Core.
Using the Azure Service Bus library as an example, complete the following steps:
.NET CLI
2. Create or register the library's client. The distro supports both cases.
C#
3. In appsettings.json, change the Service Bus library's default log level. For example, toggle
it to Debug by setting the Logging:LogLevel:Azure.Messaging.ServiceBus key as follows:
JSON
{
"ConnectionStrings": {
"ServiceBus": "<connection_string>"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Azure.Messaging.ServiceBus": "Debug"
}
},
"AllowedHosts": "*"
}
7 Note
This capability applies only to libraries using HTTP to communicate with an Azure service.
Libraries based on alternative protocols, such as AMQP, don't support content logging.
Unsupported examples include libraries for Azure services such as Event Hubs, Service Bus,
and Web PubSub.
When troubleshooting unexpected behavior with a client library, it's helpful to inspect the
following items:
The HTTP request body sent to the underlying Azure service's REST API.
The HTTP response body received from the Azure service's REST API.
By default, logging of the aforementioned content is disabled. To enable logging of the HTTP
request and response bodies, complete the following steps:
1. Set the client options object's IsLoggingContentEnabled property to true , and pass the
options object to the client's constructor. For example, to log HTTP requests and
responses for the Azure Key Vault Secrets library:
C#
2. Use your preferred logging approach with an event/log level of verbose/debug or higher.
Find your approach in the following table for specific instructions.
ノ Expand table
Approach Instructions
Next steps
Enable diagnostics logging for apps in Azure App Service
Review Azure security logging and auditing options
Learn how to work with Azure platform logs
Read more about .NET logging and tracing
Pagination with the Azure SDK for .NET
Article • 04/25/2025
In this article, you'll learn how to use the Azure SDK for .NET pagination functionality to work
efficiently and productively with large data sets. Pagination is the act of dividing large data sets
into pages, making it easier for the consumer to iterate through smaller amounts of data.
Starting with C# 8, you can create and consume streams asynchronously using Asynchronous
(async) streams. Async streams are based on the IAsyncEnumerable<T> interface. The Azure
SDK for .NET exposes an implementation of IAsyncEnumerable<T> with its AsyncPageable<T>
class.
All of the samples in this article rely on the following NuGet packages:
Azure.Security.KeyVault.Secrets
Microsoft.Extensions.Azure
Microsoft.Extensions.Hosting
System.Linq.Async
For the latest directory of Azure SDK for .NET packages, see Azure SDK latest releases.
ノ Expand table
Type Description
Most of the samples in this article are asynchronous, using variations of the AsyncPageable<T>
type. Using asynchronous programming for I/O-bound operations is ideal. A perfect use case is
using the async APIs from the Azure SDK for .NET as these operations represent HTTP/S
network calls.
C#
IAsyncEnumerator<SecretProperties> enumerator =
allSecrets.GetAsyncEnumerator();
try
{
while (await enumerator.MoveNextAsync())
{
SecretProperties secret = enumerator.Current;
Console.WriteLine($"IterateSecretsWithWhileLoopAsync: {secret.Name}");
}
}
finally
{
await enumerator.DisposeAsync();
}
}
In the preceding C# code:
The MoveNextAsync() method is invoked repeatedly until there are no items to return.
C#
Convert to a List<T>
Use ToListAsync to convert an AsyncPageable<T> to a List<T> . This method might make
several service calls if the data isn't returned in a single page.
C#
secretList.ForEach(secret =>
Console.WriteLine($"ToListAsync: {secret.Name}"));
}
C#
More methods
System.Linq.Async provides other methods that provide functionality equivalent to their
C#
// ⚠️ DON'T DO THIS! 😲
int expensiveSecretCount =
await client.GetPropertiesOfSecretsAsync()
.CountAsync();
2 Warning
The same warning applies to operators like Where . Always prefer server-side filtering,
aggregation, or projections of data if available.
As an observable sequence
The System.Linq.Async package is primarily used to provide observer pattern capabilities
over IAsyncEnumerable<T> sequences. Asynchronous streams are pull-based. As their items are
iterated over, the next available item is pulled. This approach is in juxtaposition with the
observer pattern, which is push-based. As items become available, they're pushed to
subscribers who act as observers. The System.Linq.Async package provides the ToObservable
extension method that lets you convert an IAsyncEnumerable<T> to an IObservable<T>.
C#
sealed file class SecretPropertyObserver : IObserver<SecretProperties>
{
public void OnCompleted() =>
Console.WriteLine("Done observing secrets");
C#
IDisposable UseTheToObservableMethod()
{
AsyncPageable<SecretProperties> allSecrets =
client.GetPropertiesOfSecretsAsync();
return observable.Subscribe(
new SecretPropertyObserver());
}
foreach loop.
C#
void IterateWithPageable()
{
Pageable<SecretProperties> allSecrets = client.GetPropertiesOfSecrets();
) Important
While this synchronous API is available, use the asynchronous API alternatives for a better
experience.
See also
Dependency injection with the Azure SDK for .NET
Thread safety and client lifetime management for Azure SDK objects
System.Linq.Async
Task-based asynchronous pattern
Unit testing and mocking with the Azure
SDK for .NET
Article • 04/25/2025
Unit testing is an important part of a sustainable development process that can improve code
quality and prevent regressions or bugs in your apps. However, unit testing presents challenges
when the code you're testing performs network calls, such as those made to Azure resources.
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. This avoids the above issues
and lets developers focus on testing their application logic, independent from the network and
service.
In this article, you learn how to write unit tests for the Azure SDK for .NET that isolate your
dependencies to make your tests more reliable. You also learn how to replace key components
with in-memory test implementations to create fast and reliable unit tests, and see how to
design your own classes to better support unit testing. This article includes examples that use
Moq and NSubstitute , which are popular mocking libraries for .NET.
Each of the Azure SDK clients follows mocking guidelines that allow their behavior to be
overridden:
Each client offers at least one protected constructor to allow inheritance for testing.
All public client members are virtual to allow overriding.
7 Note
The code examples in this article use types from the Azure.Security.KeyVault.Secrets
library for the Azure Key Vault service. The concepts demonstrated in this article also apply
to service clients from many other Azure services, such as Azure Storage or Azure Service
Bus.
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.)
Non-library
To create a test client instance using C# without a mocking library, inherit from the client
type and override methods you're calling in your code with an implementation that
returns a set of test objects. Most clients contain both synchronous and asynchronous
methods for operations; override only the one your application code is calling.
7 Note
C#
using Azure.Security.KeyVault.Secrets;
using Azure;
using NSubstitute.Routing.Handlers;
namespace UnitTestingSampleApp.NonLibrary;
Input models are intended to be created and passed as parameters to service methods
by developers. They have one or more public constructors and writeable properties.
Output models are only returned by the service and have no public constructors or
writeable properties.
Round-trip models are less common, but are returned by the service, modified, and used
as an input.
To create a test instance of an input model, use one of the available public constructors and set
the additional properties you need.
C#
To create instances of output models, a model factory is used. Azure SDK client libraries
provide a static model factory class with a ModelFactory suffix in its name. The class contains a
set of static methods to initialize the library's output model types. For example, the model
factory for SecretClient is SecretModelFactory :
C#
7 Note
Some input models have read-only properties that are only populated when the model is
returned by the service. In this case, a model factory method will be available that allows
setting these properties. For example, SecretProperties.
C#
Non-library
The Response class is abstract, which means there are many members to override.
Consider using a library to streamline your approach.
C#
using Azure.Core;
using Azure;
using System.Diagnostics.CodeAnalysis;
namespace UnitTestingSampleApp.NonLibrary;
Some services also support using the Response<T> type, which is a class that contains a model
and the HTTP response that returned it. To create a test instance of Response<T> , use the static
Response.FromValue method:
Non-library
C#
Explore paging
The Page<T> class is used as a building block in service methods that invoke operations
returning results in multiple pages. The Page<T> is rarely returned from APIs directly but is
useful to create the AsyncPageable<T> and Pageable<T> instances in the next section. To create
a Page<T> instance, use the Page<T>.FromValues method, passing a list of items, a
continuation token, and the Response .
The continuationToken parameter is used to retrieve the next page from the service. For unit
testing purposes, it should be set to null for the last page and should be nonempty for other
pages.
Non-library
C#
AsyncPageable<T> and Pageable<T> are classes that represent collections of models returned
by the service in pages. The only difference between them is that one is used with synchronous
methods while the other is used with asynchronous methods.
To create a test instance of Pageable or AsyncPageable , use the FromPages static method:
Non-library
C#
C#
using Azure.Security.KeyVault.Secrets;
return secretsAboutToExpire.ToArray();
}
}
You want to test the following behaviors of the AboutToExpireSecretFinder to ensure they
continue working as expected:
Non-library
C#
using Azure;
using Azure.Security.KeyVault.Secrets;
namespace UnitTestingSampleApp.NonLibrary;
// Act
string[] soonToExpire = await finder.GetAboutToExpireSecretsAsync();
// Assert
Assert.Empty(soonToExpire);
}
[Fact]
public async Task ReturnsSecretsThatExpireSoon()
{
// Arrange
// Act
string[] soonToExpire = await finder.GetAboutToExpireSecretsAsync();
// Assert
Assert.Equal(new[] { "secret1", "secret2" }, soonToExpire);
}
}
C#
The simplest refactoring you can do to enable testing with dependency injection would be to
expose the client as a parameter and run default creation code when no value is provided. This
approach allows you to make the class testable while still retaining the flexibility of using the
type without much ceremony.
C#
Another option is to move the dependency creation entirely into the calling code:
C#
This approach is useful when you would like to consolidate the dependency creation and share
the client between multiple consuming classes.
For example, an Azure virtual machine exists in an Azure resource group. The
Azure.ResourceManager.Compute namespace models the Azure virtual machine as
C#
VirtualMachineCollection virtualMachineCollection =
resourceGroup.GetVirtualMachines();
mock of the type and override the method. Instead, you'll also have to create a mock class for
the "mockable resource" and wire them together.
The mockable resource type is always in the Mocking sub-namespace of the extension method.
In the preceding example, the mockable resource type is in the
Azure.ResourceManager.Compute.Mocking namespace. The mockable resource type is always
named after the resource type with "Mockable" and the library name as prefixes. In the
preceding example, the mockable resource type is named
MockableComputeResourceGroupResource , where ResourceGroupResource is the resource type of
One more requirement before you get the unit test running is to mock the GetCachedClient
method on the resource type of the extension method. Completing this step hooks up the
extension method and the method on the mockable resource type.
Non-library
C#
using Azure.Core;
namespace UnitTestingSampleApp.ResourceManager.NonLibrary;
See also
Dependency injection in .NET
Unit testing best practices
Unit testing C# in .NET using dotnet test and xUnit
Configure a proxy when using the Azure
SDK for .NET
Article • 04/25/2025
If your organization requires the use of a proxy server to access Internet resources, some
configuration is required to use the Azure SDK for .NET client libraries. Once configured, the
proxy is applied to the underlying HttpClient instance used for HTTP operations.
The proxy can be configured via code or via an environment variable. The approach you
choose depends on the desired behavior. Set the appropriate environment variable if you want
the proxy to apply globally to all service clients created within the current process.
Alternatively, configure the proxy via code to selectively apply the settings to service clients.
) Important
3. Pass the service client options object to the service client constructor.
Using the Azure Key Vault Secrets library as an example, you'd have the following code:
C#
using System.Net;
using Azure.Core.Pipeline;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
ノ Expand table
ALL_PROXY or all_proxy The proxy server used for both HTTP and HTTPS requests.
GATEWAY_INTERFACE Indicator that the app is running in a Common Gateway Interface (CGI)
environment. Example value: CGI/1.1
For a deep understanding of how these environment variables are processed, see the code .
Be aware of the following behaviors:
get the IP address or hostname, port, and credentials for your proxy server, consult your
network administrator.
The following examples show how to set the appropriate environment variables in command
shell (Windows) and bash (Linux/macOS) environments. Setting the appropriate environment
variable causes the Azure SDK for .NET libraries to use the proxy server at runtime.
cmd
The Azure SDK client libraries provide an interface to Azure services by translating method calls
into messages sent via the respective service protocol. For REST API services, this means
sending HTTP requests and converting the responses into runtime types. In this article, you'll
learn about the different types of methods exposed by the client libraries and explore their
implementation patterns.
Protocol methods provide a thin wrapper around the underlying REST API for a
corresponding Azure service. These methods map primitive input parameters to HTTP
request values and return a raw HTTP response object.
Convenience methods provide a convenience layer over the lower-level protocol layer to
add support for the .NET type system and other benefits. Convenience methods accept
primitives or .NET model types as parameters and map them to the body of an underlying
REST API request. These methods also handle various details of request and response
management to allow developers to focus on sending and receiving data objects, instead
of lower-level concerns.
Azure.Core provides shared primitives, abstractions, and helpers for building modern
Azure SDK client libraries. These libraries follow the Azure SDK Design Guidelines for
.NET and use package names and namespaces prefixed with Azure, such as
Azure.Storage.Blobs.
System.ClientModel is a core library that provides shared primitives, abstractions, and
helpers for .NET service client libraries. The System.ClientModel library is a general
purpose toolset designed to help build libraries for various platforms and services,
whereas the Azure.Core library is specifically designed for building Azure client libraries.
7 Note
The Azure.Core library itself also depends on System.ClientModel for various client
building blocks. In the context of this article, the key differentiator for method patterns is
whether a client library depends on Azure.Core or System.ClientModel directly, rather
than through a transitive dependency.
The following table compares some of the request and response types used by protocol and
convenience methods, based on whether the library depends on Azure.Core or
System.ClientModel .
ノ Expand table
Convenience method
using Azure.AI.ContentSafety;
using Azure.Identity;
Convenience method
Consider the following code that uses a ChatClient to call the CompleteChat convenience
method:
C#
using OpenAI.Chat;
Handle exceptions
When a service call fails, the service client throws an exception that exposes the HTTP status
code and the details of the service response, if available. A System.ClientModel -dependent
library throws a ClientResultException, while an Azure.Core -dependent library throws a
RequestFailedException.
System.ClientModel exceptions
C#
using Azure.AI.ContentSafety;
using Azure.Identity;
using Azure;
try
{
// Call the convenience method
AnalyzeTextResult result = client.AnalyzeText("What is Microsoft Azure?");
Convenience methods:
Enable you to work with more friendly method parameter and response types.
Handle various low-level concerns and optimizations for you.
Protocol methods:
See also
Understanding the Azure Core library for .NET
Azure SDK for .NET package index
Article • 04/25/2025
All libraries
beta.2 beta.2
beta.1 beta.1
Azure client library integration for ASP.NET Core NuGet 1.11.0 docs GitHub 1.11.0
Blob Storage Key Store for .NET Data Protection NuGet 1.5.0 docs GitHub 1.5.0
CloudNative CloudEvents with Event Grid NuGet 1.0.0 docs GitHub 1.0.0
Core - Client - Spatial Newtonsoft Json NuGet 1.0.0 docs GitHub 1.0.0
NuGet 1.1.0- GitHub 1.1.0-
beta.1 beta.1
Functions extension for Azure Tables NuGet 1.3.3 docs GitHub 1.3.3
Key Encryptor for .NET Data Protection NuGet 1.4.0 docs GitHub 1.4.0
Secrets Configuration Provider for .NET NuGet 1.4.0 docs GitHub 1.4.0
Functions extension for Blob Storage NuGet 5.3.4 docs GitHub 5.3.4
Functions extension for Storage Queues NuGet 5.3.4 docs GitHub 5.3.4
Functions extension for WebPubSub for SocketIO NuGet 1.0.0- docs GitHub 1.0.0-
beta.4 beta.4
Name Package Docs Source
Resource Management - App Compliance Automation NuGet 1.0.1 docs GitHub 1.0.1
Resource Management - Azure Stack HCI NuGet 1.2.1 docs GitHub 1.2.1
Resource Management - Azure VMware Solution NuGet 1.4.0 docs GitHub 1.4.0
Resource Management - Connected VMware vSphere NuGet 1.1.1 docs GitHub 1.1.1
beta.1 beta.1
Resource Management - Container Orchestrator Runtime NuGet 1.0.0- docs GitHub 1.0.0-
beta.1 beta.1
Resource Management - Container Service Fleet NuGet 1.1.0 docs GitHub 1.1.0
Resource Management - Content Delivery Network NuGet 1.3.1 docs GitHub 1.3.1
Resource Management - Cosmos DB for PostgreSQL NuGet 1.0.0 docs GitHub 1.0.0
NuGet 1.1.0- GitHub 1.1.0-
beta.2 beta.2
Resource Management - Data Box Edge NuGet 1.1.1 docs GitHub 1.1.1
Resource Management - Data Lake Analytics NuGet 1.1.1 docs GitHub 1.1.1
Resource Management - Data Lake Store NuGet 1.1.1 docs GitHub 1.1.1
Resource Management - Database Fleet Manager NuGet 1.0.0- docs GitHub 1.0.0-
beta.1 beta.1
Name Package Docs Source
Resource Management - Device Provisioning Services NuGet 1.2.1 docs GitHub 1.2.1
Resource Management - Hardware Security Modules NuGet 1.0.0- docs GitHub 1.0.0-
beta.4 beta.4
Resource Management - Health Data AI Services NuGet 1.0.0 docs GitHub 1.0.0
Resource Management - Hybrid Container Service NuGet 1.0.1 docs GitHub 1.0.1
Resource Management - Informatica Data Management NuGet 1.0.0- docs GitHub 1.0.0-
beta.1 beta.1
Resource Management - IoT Firmware Defense NuGet 1.0.1 docs GitHub 1.0.1
Resource Management - Machine Learning Compute NuGet 1.0.0- docs GitHub 1.0.0-
beta.5 beta.5
Resource Management - Managed Network Fabric NuGet 1.1.2 docs GitHub 1.1.2
Resource Management - Managed Service Identity NuGet 1.2.3 docs GitHub 1.2.3
NuGet 1.3.0- GitHub 1.3.0-
beta.1 beta.1
Resource Management - Migration Discovery SAP NuGet 1.0.0- docs GitHub 1.0.0-
beta.2 beta.2
Resource Management - New Relic Observability NuGet 1.1.1 docs GitHub 1.1.1
Resource Management - Palo Alto Networks - Next NuGet 1.1.1 docs GitHub 1.1.1
Generation Firewall
beta.5 beta.5
Resource Management - Recovery Services Backup NuGet 1.3.0 docs GitHub 1.3.0
Resource Management - Recovery Services Data Replication NuGet 1.0.0 docs GitHub 1.0.0
Resource Management - Recovery Services Site Recovery NuGet 1.2.1 docs GitHub 1.2.1
Resource Management - Redis Enterprise Cache NuGet 1.0.0- docs GitHub 1.0.0-
beta.1 beta.1
Resource Management - Service Fabric Managed Clusters NuGet 1.2.0 docs GitHub 1.2.0
NuGet 1.3.0- GitHub 1.3.0-
beta.2 beta.2
Resource Management - Spring App Discovery NuGet 1.0.0- docs GitHub 1.0.0-
beta.2 beta.2
Resource Management - SQL Virtual Machine NuGet 1.1.1 docs GitHub 1.1.1
GitHub 2.0.0-
beta.1
beta.1 beta.1
Azure client library integration for ASP.NET Core NuGet 1.11.0 docs GitHub
1.11.0
Blob Storage Key Store for .NET Data Protection NuGet 1.5.0 docs GitHub 1.5.0
CloudNative CloudEvents with Event Grid NuGet 1.0.0 docs GitHub 1.0.0
Functions extension for Azure Tables NuGet 1.3.3 docs GitHub 1.3.3
Key Encryptor for .NET Data Protection NuGet 1.4.0 docs GitHub 1.4.0
Secrets Configuration Provider for .NET NuGet 1.4.0 docs GitHub 1.4.0
Functions extension for Blob Storage NuGet 5.3.4 docs GitHub 5.3.4
Functions extension for Storage Queues NuGet 5.3.4 docs GitHub 5.3.4
Functions extension for WebPubSub for SocketIO NuGet 1.0.0- docs GitHub 1.0.0-
beta.4 beta.4
Resource Management - App Compliance Automation NuGet 1.0.1 docs GitHub 1.0.1
Resource Management - Azure Stack HCI NuGet 1.2.1 docs GitHub 1.2.1
Resource Management - Azure VMware Solution NuGet 1.4.0 docs GitHub 1.4.0
Resource Management - Connected VMware vSphere NuGet 1.1.1 docs GitHub 1.1.1
Resource Management - Container Orchestrator Runtime NuGet 1.0.0- docs GitHub 1.0.0-
beta.1 beta.1
Resource Management - Container Service Fleet NuGet 1.1.0 docs GitHub 1.1.0
Resource Management - Content Delivery Network NuGet 1.3.1 docs GitHub 1.3.1
Resource Management - Data Box Edge NuGet 1.1.1 docs GitHub 1.1.1
Resource Management - Data Lake Analytics NuGet 1.1.1 docs GitHub 1.1.1
Resource Management - Data Lake Store NuGet 1.1.1 docs GitHub 1.1.1
Resource Management - Database Fleet Manager NuGet 1.0.0- docs GitHub 1.0.0-
beta.1 beta.1
Resource Management - Device Provisioning Services NuGet 1.2.1 docs GitHub 1.2.1
Resource Management - Hardware Security Modules NuGet 1.0.0- docs GitHub 1.0.0-
beta.4 beta.4
Resource Management - Health Data AI Services NuGet 1.0.0 docs GitHub 1.0.0
Resource Management - Hybrid Container Service NuGet 1.0.1 docs GitHub 1.0.1
Resource Management - Informatica Data Management NuGet 1.0.0- docs GitHub 1.0.0-
beta.1 beta.1
Resource Management - IoT Firmware Defense NuGet 1.0.1 docs GitHub 1.0.1
Resource Management - Machine Learning Compute NuGet 1.0.0- docs GitHub 1.0.0-
beta.5 beta.5
Resource Management - Managed Network Fabric NuGet 1.1.2 docs GitHub 1.1.2
Resource Management - Migration Discovery SAP NuGet 1.0.0- docs GitHub 1.0.0-
beta.2 beta.2
Resource Management - New Relic Observability NuGet 1.1.1 docs GitHub 1.1.1
Resource Management - Palo Alto Networks - Next Generation NuGet 1.1.1 docs GitHub 1.1.1
Firewall
Resource Management - Recovery Services Backup NuGet 1.3.0 docs GitHub 1.3.0
Resource Management - Recovery Services Data Replication NuGet 1.0.0 docs GitHub 1.0.0
Resource Management - Recovery Services Site Recovery NuGet 1.2.1 docs GitHub 1.2.1
Resource Management - Redis Enterprise Cache NuGet 1.0.0- docs GitHub 1.0.0-
beta.1 beta.1
Resource Management - Service Fabric Managed Clusters NuGet 1.2.0 docs GitHub
NuGet 1.3.0- 1.2.0
beta.2 GitHub 1.3.0-
beta.2
Resource Management - Spring App Discovery NuGet 1.0.0- docs GitHub 1.0.0-
beta.2 beta.2
Resource Management - SQL Virtual Machine NuGet 1.1.1 docs GitHub 1.1.1
NuGet 1.19.1-
preview-001
Microsoft.Azure.Devices NuGet
1.40.0
NuGet 2.0.0-
preview007
Microsoft.Azure.Devices.Provisioning.Client NuGet
1.19.1
NuGet 1.20.0-
preview-001
Microsoft.Azure.Devices.Provisioning.Security.Tpm NuGet
1.14.1
NuGet 1.15.0-
preview-001
Microsoft.Azure.Devices.Provisioning.Transport.Amqp NuGet
1.16.1
NuGet 1.17.0-
preview-001
Microsoft.Azure.Devices.Provisioning.Transport.Http NuGet
1.15.1
NuGet 1.16.0-
preview-001
Microsoft.Azure.Devices.Provisioning.Transport.Mqtt NuGet
1.17.1
NuGet 1.18.0-
preview-001
Name Package Docs Source
Microsoft.Azure.Devices.Shared NuGet
1.30.1
NuGet 1.31.0-
preview-001
Functions extension for Azure Mobile Apps NuGet 3.0.0- GitHub 3.0.0-
beta8 beta8
Functions extension for Azure SQL and SQL Server NuGet 3.1.376
Functions extension for Durable Task Framework NuGet 3.1.0 docs GitHub 3.1.0
Functions item template pack for Microsoft Template Engine NuGet GitHub
4.0.5086 4.0.5086
Functions project template pack for Microsoft Template Engine NuGet GitHub
4.0.5086 4.0.5086
Functions runtime assemblies for App Insights logging NuGet 3.0.41 GitHub
3.0.41
Microsoft.Azure.Functions.Worker.ItemTemplates NuGet
4.0.5086
Name Package Docs Source
Microsoft.Azure.Functions.Worker.ProjectTemplates NuGet
4.0.5086
Services