diff --git a/.openpublishing.redirection.ai.json b/.openpublishing.redirection.ai.json index 8c73dbebb51da..b163e96c7859a 100644 --- a/.openpublishing.redirection.ai.json +++ b/.openpublishing.redirection.ai.json @@ -3,6 +3,14 @@ { "source_path_from_root": "/docs/ai/quickstarts/get-started-azure-openai.md", "redirect_url": "/dotnet/ai/quickstarts/get-started-openai" + }, + { + "source_path_from_root": "/docs/ai/how-to/use-redis-for-memory.md", + "redirect_url": "/dotnet/ai" + }, + { + "source_path_from_root": "/docs/ai/how-to/work-with-local-models.md", + "redirect_url": "/dotnet/ai" } ] } \ No newline at end of file diff --git a/docfx.json b/docfx.json index 2ab4a468a1a6b..9c2b5973f1b6a 100644 --- a/docfx.json +++ b/docfx.json @@ -256,6 +256,7 @@ "docs/core/runtime-config/**.md": "reference", "docs/core/tools/dotnet*.md": "reference", "docs/core/tools/sdk-errors/*.md": "error-reference", + "docs/core/testing/mstest-analyzers/*.md": "error-reference", "docs/core/tutorials/**.md": "tutorial", "docs/csharp/getting-started/**/*.md": "overview", "docs/csharp/how-to/**/*.md": "how-to", @@ -268,7 +269,7 @@ "docs/csharp/roslyn-sdk/tutorials/*.md": "tutorial", "docs/csharp/tour-of-csharp/tutorials/**": "tutorial", "docs/csharp/tutorials/**": "tutorial", - "docs/framework/additional-apis/**/**.md": "managed-reference", + "docs/framework/additional-apis/**/**.md": "reference", "docs/framework/configure-apps/file-schema/**/**.md": "reference", "docs/framework/data/adonet/ef/language-reference/*-entity-sql.md": "language-reference", "docs/framework/debug-trace-profile/*-mda.md": "reference", @@ -286,8 +287,8 @@ "docs/framework/**/troubleshooting*.md": "troubleshooting", "docs/fsharp/language-reference/**/**.md": "language-reference", "docs/iot/**/*.*": "conceptual", - "docs/fundamentals/code-analysis/quality-rules/**.md": "reference", - "docs/fundamentals/code-analysis/style-rules/**.md": "reference", + "docs/fundamentals/code-analysis/quality-rules/**.md": "error-reference", + "docs/fundamentals/code-analysis/style-rules/**.md": "error-reference", "docs/fundamentals/diagnostics/runtime-*.md": "reference", "docs/fundamentals/syslib-diagnostics/**/*.md": "error-reference", "docs/standard/**/*how-to*.md": "how-to", diff --git a/docs/ai/how-to/use-redis-for-memory.md b/docs/ai/how-to/use-redis-for-memory.md deleted file mode 100644 index 2015b7c3d870f..0000000000000 --- a/docs/ai/how-to/use-redis-for-memory.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: "Use Redis for Memory Storage with the Semantic Kernel SDK" -description: "Learn how to use a Redis database together with the RediSearch module to give your AI memories in Semantic Kernel SDK for .NET." -author: haywoodsloan -ms.topic: how-to -ms.date: 04/17/2024 - -#customer intent: As a .NET developer, I want to use Redis for memory storage together with the Semantic Kernel SDK so that I can store and recall memories in my application. - ---- - -# Use Redis for memory storage with the Semantic Kernel SDK - -This article demonstrates how to integrate a Redis database with the RediSearch module into the [Semantic Kernel SDK](/semantic-kernel/overview) and use it for memory storage and retrieval. - -[Vector stores](/semantic-kernel/concepts/vector-store-connectors/) represent text information that has been stored alongside a precomputed embedding vector for the whole text. When an LLM is prompted to recall a memory, it uses these precomputed embeddings to efficiently evaluate whether a memory is relevant to the prompt. After the LLM finds a matching memory, it uses the memory's text information as context for the next steps in the prompt completion. - -Memory storage that's added to the Semantic Kernel SDK provides a broader context for your requests. It also enables you to store data in the same manner as you store a traditional database, but query it by using natural language. - -## Prerequisites - -* An Azure account that has an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F). -* [.NET SDK](https://dotnet.microsoft.com/download/visual-studio-sdks) -* [`Microsoft.SemanticKernel` NuGet package](https://www.nuget.org/packages/Microsoft.SemanticKernel) -* [`Microsoft.SemanticKernel.Connectors.Redis` NuGet package](https://www.nuget.org/packages/Microsoft.SemanticKernel.Connectors.Redis) -* [`Microsoft.SemanticKernel.Plugins.Memory` NuGet package](https://www.nuget.org/packages/Microsoft.SemanticKernel.Plugins.Memory) -* [`StackExchange.Redis` NuGet package](https://www.nuget.org/packages/StackExchange.Redis) -* A Redis database that has the RediSearch module, [deployed and accessible to your .NET application](/azure/azure-cache-for-redis/quickstart-create-redis-enterprise) - -## Implement memory storage using a Redis database - -Before you integrate your Redis database to the Semantic Kernel SDK, make sure that you have the RediSearch module enabled. For module information for _Azure Cache for Redis_, see [Use Redis modules with Azure Cache for Redis](/azure/azure-cache-for-redis/cache-redis-modules#adding-modules-to-your-cache). - -1. Initialize a connection to your Redis database. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/MemoryExamples.cs" id="initRedis"::: - -2. Build the `Kernel` by including `ITextEmbeddingGenerationService`. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/MemoryExamples.cs" id="initKernel"::: - -3. Wrap the Redis database in a `RedisMemoryStore` instance, and then initialize a `SemanticTextMemory` object by using the memory store and embedding generation service. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/MemoryExamples.cs" id="initMemory"::: - -4. Add the semantic text memory to the `Kernel` by using the `TextMemoryPlugin` class. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/MemoryExamples.cs" id="addMemory"::: - -5. Use the `Kernel` and plug-in to save, retrieve, and recall memories. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/MemoryExamples.cs" id="useMemory"::: - -6. Use memory recall as part of a prompt by using the [prompt template syntax `{{...}}`](/semantic-kernel/prompts/prompt-template-syntax). For example: - - :::code language="csharp" source="./snippets/semantic-kernel/MemoryExamples.cs" id="promptMemory"::: - -## Related content - -* [Working with vector databases](../tutorials/tutorial-ai-vector-search.md) -* [Chat using your own data sample for .NET](../get-started-app-chat-template.md) diff --git a/docs/ai/how-to/work-with-local-models.md b/docs/ai/how-to/work-with-local-models.md deleted file mode 100644 index c6643560c51a5..0000000000000 --- a/docs/ai/how-to/work-with-local-models.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: "Use Custom and Local AI Models with the Semantic Kernel SDK for .NET" -titleSuffix: "" -description: "Learn how to use custom or local models for text generation and chat completions in Semantic Kernel SDK for .NET." -author: haywoodsloan -ms.topic: how-to -ms.date: 04/11/2024 - -#customer intent: As a .NET developer, I want to use custom or local AI models with the Semantic Kernel SDK so that I can perform text generation and chat completions using any model available to me. - ---- - -# Use custom and local AI models with the Semantic Kernel SDK - -This article demonstrates how to integrate custom and local models into the [Semantic Kernel SDK](/semantic-kernel/overview) and use them for text generation and chat completions. - -You can adapt the steps to use them with any model that you can access, regardless of where or how you access it. For example, you can integrate the [codellama](https://ollama.com/library/codellama) model with the Semantic Kernel SDK to enable code generation and discussion. - -Custom and local models often provide access via REST APIs. For example, see [Ollama OpenAI compatibility](https://ollama.com/blog/openai-compatibility). Before you integrate your model, it will need to be hosted and accessible to your .NET application via HTTPS. - -## Prerequisites - -* An Azure account with an active subscription. [Create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F). -* [.NET SDK](https://dotnet.microsoft.com/download/visual-studio-sdks) -* [`Microsoft.SemanticKernel` NuGet package](https://www.nuget.org/packages/Microsoft.SemanticKernel) -* A custom or local model, deployed and accessible to your .NET application - -## Implement text generation using a local model - -The following section shows how you can integrate your model with the Semantic Kernel SDK and then use it to generate text completions. - -1. Create a service class that implements the `ITextGenerationService` interface. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/services/MyTextGenerationService.cs" id="service"::: - -2. Include the new service class when building the `Kernel`. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/LocalModelExamples.cs" id="addTextService"::: - -3. Send a text generation prompt to your model directly through the `Kernel` or using the service class. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/LocalModelExamples.cs" id="useTextService"::: - -## Implement chat completion using a local model - -The following section shows how you can integrate your model with the Semantic Kernel SDK and then use it for chat completions. - -1. Create a service class that implements the `IChatCompletionService` interface. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/services/MyChatCompletionService.cs" id="service"::: - -2. Include the new service class when building the `Kernel`. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/LocalModelExamples.cs" id="addChatService"::: - -3. Send a chat completion prompt to your model directly through the `Kernel` or using the service class. For example: - - :::code language="csharp" source="./snippets/semantic-kernel/LocalModelExamples.cs" id="useChatService"::: - -## Related content - -* [What is Semantic Kernel](/semantic-kernel/overview/) -* [Understanding AI plugins in Semantic Kernel](/semantic-kernel/agents/plugins/?tabs=Csharp) diff --git a/docs/ai/quickstarts/quickstart-assistants.md b/docs/ai/quickstarts/quickstart-assistants.md index c2fa6918f82bd..e9a60417009b6 100644 --- a/docs/ai/quickstarts/quickstart-assistants.md +++ b/docs/ai/quickstarts/quickstart-assistants.md @@ -133,5 +133,4 @@ Complete the following steps to create a .NET console app and add the package ne ## Next steps -- [Quickstart - Get insight about your data from an .NET Azure AI chat app](../how-to/work-with-local-models.md) - [Generate text and conversations with .NET and Azure OpenAI Completions](/training/modules/open-ai-dotnet-text-completions/) diff --git a/docs/ai/quickstarts/quickstart-local-ai.md b/docs/ai/quickstarts/quickstart-local-ai.md index 26f8557c92dae..8bd22c102f4d5 100644 --- a/docs/ai/quickstarts/quickstart-local-ai.md +++ b/docs/ai/quickstarts/quickstart-local-ai.md @@ -146,5 +146,4 @@ The Semantic Kernel SDK provides many services and features to connect to AI mod ## Next steps -- [Quickstart - Get insight about your data from an .NET Azure AI chat app](../how-to/work-with-local-models.md) - [Generate text and conversations with .NET and Azure OpenAI Completions](/training/modules/open-ai-dotnet-text-completions/) diff --git a/docs/ai/toc.yml b/docs/ai/toc.yml index 103022e2b89fb..0220fb5b64337 100644 --- a/docs/ai/toc.yml +++ b/docs/ai/toc.yml @@ -55,12 +55,8 @@ items: items: - name: Authenticate to Azure OpenAI from an Azure hosted app href: how-to/app-service-aoai-auth.md - - name: Authenticate App Service to a vector database + - name: Authenticate to Azure Databases from an Azure hosted app href: how-to/app-service-db-auth.md - - name: Use Redis with Semantic Kernel - href: how-to/use-redis-for-memory.md - - name: Use custom & local AI models with Semantic Kernel - href: how-to/work-with-local-models.md - name: Work with content filtering href: how-to/content-filtering.md - name: Tutorials diff --git a/docs/architecture/cloud-native/identity-server.md b/docs/architecture/cloud-native/identity-server.md index 6725202e50614..cf10e0ea14d8e 100644 --- a/docs/architecture/cloud-native/identity-server.md +++ b/docs/architecture/cloud-native/identity-server.md @@ -1,7 +1,7 @@ --- title: IdentityServer for Cloud Native Apps description: Architecting Cloud Native .NET Apps for Azure | IdentityServer -ms.date: 04/06/2022 +ms.date: 02/06/2025 --- # IdentityServer for cloud-native applications @@ -26,7 +26,7 @@ Typically, applications need to support some or all of the following scenarios: In each of these scenarios, the exposed functionality needs to be secured against unauthorized use. At a minimum, this typically requires authenticating the user or principal making a request for a resource. This authentication may use one of several common protocols such as SAML2p, WS-Fed, or OpenID Connect. Communicating with APIs typically uses the OAuth2 protocol and its support for security tokens. Separating these critical cross-cutting security concerns and their implementation details from the applications themselves ensures consistency and improves security and maintainability. Outsourcing these concerns to a dedicated product like IdentityServer helps the requirement for every application to solve these problems itself. -IdentityServer provides middleware that runs within an ASP.NET Core application and adds support for OpenID Connect and OAuth2 (see [supported specifications](https://docs.duendesoftware.com/identityserver/v6/overview/specs/)). Organizations would create their own ASP.NET Core app using IdentityServer middleware to act as the STS for all of their token-based security protocols. The IdentityServer middleware exposes endpoints to support standard functionality, including: +IdentityServer provides middleware that runs within an ASP.NET Core application and adds support for OpenID Connect and OAuth2 (see [supported specifications](https://docs.duendesoftware.com/identityserver/v7/overview/specs/)). Organizations would create their own ASP.NET Core app using IdentityServer middleware to act as the STS for all of their token-based security protocols. The IdentityServer middleware exposes endpoints to support standard functionality, including: - Authorize (authenticate the end user) - Token (request a token programmatically) @@ -39,57 +39,52 @@ IdentityServer provides middleware that runs within an ASP.NET Core application ## Getting started -IdentityServer4 is available under dual license: +IdentityServer is available: -* RPL - lets you use the IdentityServer4 free if used in open-source work -* Paid - lets you use the IdentityServer4 in a commercial scenario +* With a community license, which lets you use the [IdentityServer free for small companies and non-profits](https://duendesoftware.com/products/communityedition) (conditions apply) +* Paid, which lets you use the IdentityServer [in a commercial scenario](https://duendesoftware.com/products/identityserver) For more information about pricing, see the official product's [pricing page](https://duendesoftware.com/products/identityserver). -You can add it to your applications using its NuGet packages. The main package is [IdentityServer4](https://www.nuget.org/packages/IdentityServer4/), which has been downloaded over four million times. The base package doesn't include any user interface code and only supports in-memory configuration. To use it with a database, you'll also want a data provider like [IdentityServer4.EntityFramework](https://www.nuget.org/packages/IdentityServer4.EntityFramework), which uses Entity Framework Core to store configuration and operational data for IdentityServer. For user interface, you can copy files from the [Quickstart UI repository](https://github.com/IdentityServer/IdentityServer4.Quickstart.UI) into your ASP.NET Core MVC application to add support for sign in and sign out using IdentityServer middleware. +You can add it to your applications using its NuGet packages. The main package is [IdentityServer](https://www.nuget.org/packages/Duende.IdentityServer/), which has been downloaded over four million times. The base package doesn't include any user interface code and only supports in-memory configuration. To use it with a database, you'll also want a data provider like [Duende.IdentityServer.Storage](https://www.nuget.org/packages/Duende.IdentityServer.Storage), which uses Entity Framework Core to store configuration and operational data for IdentityServer. For user interface, you can copy files from the [Quickstart UI repository](https://github.com/DuendeSoftware/IdentityServer.Quickstart.UI) into your ASP.NET Core MVC application to add support for sign in and sign out using IdentityServer middleware. ## Configuration -IdentityServer supports different kinds of protocols and social authentication providers that can be configured as part of each custom installation. This is typically done in the ASP.NET Core application's `Program` class (or in the `Startup` class in the `ConfigureServices` method). The configuration involves specifying the supported protocols and the paths to the servers and endpoints that will be used. Figure 8-2 shows an example configuration taken from the IdentityServer4 Quickstart UI project: +IdentityServer supports different kinds of protocols and social authentication providers that can be configured as part of each custom installation. This is typically done in the ASP.NET Core application's `Program` class (or in the `Startup` class in the `ConfigureServices` method). The configuration involves specifying the supported protocols and the paths to the servers and endpoints that will be used. Figure 8-2 shows an example configuration taken from the [IdentityServer Quickstart for ASP.NET Core applications](https://docs.duendesoftware.com/identityserver/v7/quickstarts/2_interactive/) project: ```csharp -public class Startup -{ - public void ConfigureServices(IServiceCollection services) +// some details omitted +builder.Services.AddIdentityServer(); + +builder.Services.AddAuthentication(options => + { + options.DefaultScheme = "Cookies"; + options.DefaultChallengeScheme = "oidc"; + }) + .AddCookie("Cookies") + .AddGoogle("Google", options => + { + options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; + + options.ClientId = ""; + options.ClientSecret = ""; + }) + .AddOpenIdConnect("oidc", options => { - services.AddMvc(); - - // some details omitted - services.AddIdentityServer(); - - services.AddAuthentication() - .AddGoogle("Google", options => - { - options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; - - options.ClientId = ""; - options.ClientSecret = ""; - }) - .AddOpenIdConnect("demoidsrv", "IdentityServer", options => - { - options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme; - options.SignOutScheme = IdentityServerConstants.SignoutScheme; - - options.Authority = "https://demo.identityserver.io/"; - options.ClientId = "implicit"; - options.ResponseType = "id_token"; - options.SaveTokens = true; - options.CallbackPath = new PathString("/signin-idsrv"); - options.SignedOutCallbackPath = new PathString("/signout-callback-idsrv"); - options.RemoteSignOutPath = new PathString("/signout-idsrv"); - - options.TokenValidationParameters = new TokenValidationParameters - { - NameClaimType = "name", - RoleClaimType = "role" - }; - }); - } + options.Authority = "https://localhost:5001"; + + options.ClientId = "web"; + options.ClientSecret = "secret"; + options.ResponseType = "code"; + + options.Scope.Clear(); + options.Scope.Add("openid"); + options.Scope.Add("profile"); + + options.MapInboundClaims = false; // Don't rename claim types + + options.SaveTokens = true; + }); } ``` @@ -97,13 +92,13 @@ public class Startup ## JavaScript clients -Many cloud-native applications use server-side APIs and rich client single page applications (SPAs) on the front end. IdentityServer ships a [JavaScript client](https://docs.duendesoftware.com/identityserver/v6/quickstarts/js_clients/) (`oidc-client.js`) via NPM that can be added to SPAs to enable them to use IdentityServer for sign in, sign out, and token-based authentication of web APIs. +Many cloud-native applications use server-side APIs and rich client single page applications (SPAs) on the front end. IdentityServer ships a [JavaScript client](https://docs.duendesoftware.com/identityserver/v7/quickstarts/js_clients/) (`oidc-client.js`) via NPM that can be added to SPAs to enable them to use IdentityServer for sign in, sign out, and token-based authentication of web APIs. In addition, you can use a [backend-for-frontend (BFF)](https://docs.duendesoftware.com/identityserver/v7/quickstarts/js_clients/js_with_backend/) that implements all of the security protocol interactions with the token server and the IETF's [OAuth 2.0 for Browser-Based Applications spec](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps). ## References -- [IdentityServer documentation](https://docs.duendesoftware.com/identityserver/v6/) +- [IdentityServer documentation](https://docs.duendesoftware.com/identityserver/v7/) - [Application types](/azure/active-directory/develop/app-types) -- [JavaScript OIDC client](https://docs.duendesoftware.com/identityserver/v6/quickstarts/js_clients/) +- [JavaScript OIDC client](https://docs.duendesoftware.com/identityserver/v7/quickstarts/js_clients/) >[!div class="step-by-step"] >[Previous](azure-active-directory.md) diff --git a/docs/azure/includes/dotnet-all.md b/docs/azure/includes/dotnet-all.md index 7b475c9cd42af..777dca0fa1f70 100644 --- a/docs/azure/includes/dotnet-all.md +++ b/docs/azure/includes/dotnet-all.md @@ -28,7 +28,7 @@ | Content Safety | NuGet [1.0.0](https://www.nuget.org/packages/Azure.AI.ContentSafety/1.0.0) | [docs](/dotnet/api/overview/azure/AI.ContentSafety-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.ContentSafety_1.0.0/sdk/contentsafety/Azure.AI.ContentSafety/) | | Conversational Language Understanding | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.Language.Conversations/1.1.0)
NuGet [2.0.0-beta.2](https://www.nuget.org/packages/Azure.AI.Language.Conversations/2.0.0-beta.2) | [docs](/dotnet/api/overview/azure/AI.Language.Conversations-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_1.1.0/sdk/cognitivelanguage/Azure.AI.Language.Conversations/)
GitHub [2.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_2.0.0-beta.2/sdk/cognitivelanguage/Azure.AI.Language.Conversations/) | | Core - Client - AMQP | NuGet [1.3.1](https://www.nuget.org/packages/Azure.Core.Amqp/1.3.1) | [docs](/dotnet/api/overview/azure/Core.Amqp-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Amqp_1.3.1/sdk/core/Azure.Core.Amqp/) | -| Core - Client - Core | NuGet [1.44.1](https://www.nuget.org/packages/Azure.Core/1.44.1) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.44.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.44.1/sdk/core/Azure.Core/) | +| Core - Client - Core | NuGet [1.45.0](https://www.nuget.org/packages/Azure.Core/1.45.0) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.45.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.45.0/sdk/core/Azure.Core/) | | Core Newtonsoft Json | NuGet [2.0.0](https://www.nuget.org/packages/Microsoft.Azure.Core.NewtonsoftJson/2.0.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.Core.NewtonsoftJson-readme) | GitHub [2.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.NewtonsoftJson_2.0.0/sdk/core/Microsoft.Azure.Core.NewtonsoftJson/) | | Core WCF Storage Queues | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Microsoft.CoreWCF.Azure.StorageQueues/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Microsoft.CoreWCF.Azure.StorageQueues-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.CoreWCF.Azure.StorageQueues_1.0.0-beta.1/sdk/extension-wcf/Microsoft.CoreWCF.Azure.StorageQueues/) | | Data Movement | NuGet [12.0.0-beta.6](https://www.nuget.org/packages/Azure.Storage.DataMovement/12.0.0-beta.6) | [docs](/dotnet/api/overview/azure/Storage.DataMovement-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [12.0.0-beta.6](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Storage.DataMovement_12.0.0-beta.6/sdk/storage/Azure.Storage.DataMovement/) | @@ -108,7 +108,7 @@ | Synapse - Monitoring | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.Analytics.Synapse.Monitoring/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/Analytics.Synapse.Monitoring-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Analytics.Synapse.Monitoring_1.0.0-beta.3/sdk/synapse/Azure.Analytics.Synapse.Monitoring/) | | Synapse - Spark | NuGet [1.0.0-preview.8](https://www.nuget.org/packages/Azure.Analytics.Synapse.Spark/1.0.0-preview.8) | [docs](/dotnet/api/overview/azure/Analytics.Synapse.Spark-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-preview.8](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Analytics.Synapse.Spark_1.0.0-preview.8/sdk/synapse/Azure.Analytics.Synapse.Spark/) | | System Events | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.Messaging.EventGrid.SystemEvents/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Messaging.EventGrid.SystemEvents-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventGrid.SystemEvents_1.0.0-beta.1/sdk/eventgrid/Azure.Messaging.EventGrid.SystemEvents/) | -| System.ClientModel | NuGet [1.2.1](https://www.nuget.org/packages/System.ClientModel/1.2.1) | [docs](/dotnet/api/overview/azure/System.ClientModel-readme) | GitHub [1.2.1](https://github.com/Azure/azure-sdk-for-net/tree/System.ClientModel_1.2.1/sdk/core/System.ClientModel/) | +| System.ClientModel | NuGet [1.3.0](https://www.nuget.org/packages/System.ClientModel/1.3.0) | [docs](/dotnet/api/overview/azure/System.ClientModel-readme) | GitHub [1.3.0](https://github.com/Azure/azure-sdk-for-net/tree/System.ClientModel_1.3.0/sdk/core/System.ClientModel/) | | Tables | NuGet [12.10.0](https://www.nuget.org/packages/Azure.Data.Tables/12.10.0) | [docs](/dotnet/api/overview/azure/Data.Tables-readme) | GitHub [12.10.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Data.Tables_12.10.0/sdk/tables/Azure.Data.Tables/) | | Text Analytics | NuGet [5.3.0](https://www.nuget.org/packages/Azure.AI.TextAnalytics/5.3.0) | [docs](/dotnet/api/overview/azure/AI.TextAnalytics-readme) | GitHub [5.3.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.TextAnalytics_5.3.0/sdk/textanalytics/Azure.AI.TextAnalytics/) | | Text Translation | NuGet [1.0.0](https://www.nuget.org/packages/Azure.AI.Translation.Text/1.0.0) | [docs](/dotnet/api/overview/azure/AI.Translation.Text-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Translation.Text_1.0.0/sdk/translation/Azure.AI.Translation.Text/) | @@ -333,7 +333,7 @@ | Resource Management - Service Fabric | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.ServiceFabric/1.1.0)
NuGet [1.2.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.ServiceFabric/1.2.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ServiceFabric-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceFabric_1.1.0/sdk/servicefabric/Azure.ResourceManager.ServiceFabric/)
GitHub [1.2.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceFabric_1.2.0-beta.1/sdk/servicefabric/Azure.ResourceManager.ServiceFabric/) | | Resource Management - Service Fabric Managed Clusters | NuGet [1.2.0](https://www.nuget.org/packages/Azure.ResourceManager.ServiceFabricManagedClusters/1.2.0)
NuGet [1.3.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.ServiceFabricManagedClusters/1.3.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.ServiceFabricManagedClusters-readme) | GitHub [1.2.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceFabricManagedClusters_1.2.0/sdk/servicefabricmanagedclusters/Azure.ResourceManager.ServiceFabricManagedClusters/)
GitHub [1.3.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceFabricManagedClusters_1.3.0-beta.2/sdk/servicefabricmanagedclusters/Azure.ResourceManager.ServiceFabricManagedClusters/) | | Resource Management - Service Linker | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.ServiceLinker/1.1.0) | [docs](/dotnet/api/overview/azure/ResourceManager.ServiceLinker-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceLinker_1.1.0/sdk/servicelinker/Azure.ResourceManager.ServiceLinker/) | -| Resource Management - Service Networking | NuGet [1.0.1](https://www.nuget.org/packages/Azure.ResourceManager.ServiceNetworking/1.0.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ServiceNetworking-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceNetworking_1.0.1/sdk/servicenetworking/Azure.ResourceManager.ServiceNetworking/) | +| Resource Management - Service Networking | NuGet [1.0.1](https://www.nuget.org/packages/Azure.ResourceManager.ServiceNetworking/1.0.1)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.ServiceNetworking/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ServiceNetworking-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceNetworking_1.0.1/sdk/servicenetworking/Azure.ResourceManager.ServiceNetworking/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceNetworking_1.1.0-beta.1/sdk/servicenetworking/Azure.ResourceManager.ServiceNetworking/) | | Resource Management - SignalR | NuGet [1.1.3](https://www.nuget.org/packages/Azure.ResourceManager.SignalR/1.1.3) | [docs](/dotnet/api/overview/azure/ResourceManager.SignalR-readme) | GitHub [1.1.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.SignalR_1.1.3/sdk/signalr/Azure.ResourceManager.SignalR/) | | Resource Management - Sphere | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.Sphere/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Sphere-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Sphere_1.0.0/sdk/sphere/Azure.ResourceManager.Sphere/) | | Resource Management - Spring App Discovery | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.SpringAppDiscovery/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.SpringAppDiscovery-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.SpringAppDiscovery_1.0.0-beta.1/sdk/springappdiscovery/Azure.ResourceManager.SpringAppDiscovery/) | diff --git a/docs/azure/includes/dotnet-new.md b/docs/azure/includes/dotnet-new.md index 013a808e88fca..dd97d3b9fe0e2 100644 --- a/docs/azure/includes/dotnet-new.md +++ b/docs/azure/includes/dotnet-new.md @@ -29,7 +29,7 @@ | Content Safety | NuGet [1.0.0](https://www.nuget.org/packages/Azure.AI.ContentSafety/1.0.0) | [docs](/dotnet/api/overview/azure/AI.ContentSafety-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.ContentSafety_1.0.0/sdk/contentsafety/Azure.AI.ContentSafety/) | | Conversational Language Understanding | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.Language.Conversations/1.1.0)
NuGet [2.0.0-beta.2](https://www.nuget.org/packages/Azure.AI.Language.Conversations/2.0.0-beta.2) | [docs](/dotnet/api/overview/azure/AI.Language.Conversations-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_1.1.0/sdk/cognitivelanguage/Azure.AI.Language.Conversations/)
GitHub [2.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Language.Conversations_2.0.0-beta.2/sdk/cognitivelanguage/Azure.AI.Language.Conversations/) | | Core - Client - AMQP | NuGet [1.3.1](https://www.nuget.org/packages/Azure.Core.Amqp/1.3.1) | [docs](/dotnet/api/overview/azure/Core.Amqp-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core.Amqp_1.3.1/sdk/core/Azure.Core.Amqp/) | -| Core - Client - Core | NuGet [1.44.1](https://www.nuget.org/packages/Azure.Core/1.44.1) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.44.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.44.1/sdk/core/Azure.Core/) | +| Core - Client - Core | NuGet [1.45.0](https://www.nuget.org/packages/Azure.Core/1.45.0) | [docs](/dotnet/api/overview/azure/Core-readme) | GitHub [1.45.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Core_1.45.0/sdk/core/Azure.Core/) | | Core Newtonsoft Json | NuGet [2.0.0](https://www.nuget.org/packages/Microsoft.Azure.Core.NewtonsoftJson/2.0.0) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.Core.NewtonsoftJson-readme) | GitHub [2.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Core.NewtonsoftJson_2.0.0/sdk/core/Microsoft.Azure.Core.NewtonsoftJson/) | | Core WCF Storage Queues | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Microsoft.CoreWCF.Azure.StorageQueues/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Microsoft.CoreWCF.Azure.StorageQueues-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.CoreWCF.Azure.StorageQueues_1.0.0-beta.1/sdk/extension-wcf/Microsoft.CoreWCF.Azure.StorageQueues/) | | Data Movement | NuGet [12.0.0-beta.6](https://www.nuget.org/packages/Azure.Storage.DataMovement/12.0.0-beta.6) | [docs](/dotnet/api/overview/azure/Storage.DataMovement-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [12.0.0-beta.6](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Storage.DataMovement_12.0.0-beta.6/sdk/storage/Azure.Storage.DataMovement/) | @@ -112,7 +112,7 @@ | Synapse - Monitoring | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.Analytics.Synapse.Monitoring/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/Analytics.Synapse.Monitoring-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Analytics.Synapse.Monitoring_1.0.0-beta.3/sdk/synapse/Azure.Analytics.Synapse.Monitoring/) | | Synapse - Spark | NuGet [1.0.0-preview.8](https://www.nuget.org/packages/Azure.Analytics.Synapse.Spark/1.0.0-preview.8) | [docs](/dotnet/api/overview/azure/Analytics.Synapse.Spark-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-preview.8](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Analytics.Synapse.Spark_1.0.0-preview.8/sdk/synapse/Azure.Analytics.Synapse.Spark/) | | System Events | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.Messaging.EventGrid.SystemEvents/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Messaging.EventGrid.SystemEvents-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Messaging.EventGrid.SystemEvents_1.0.0-beta.1/sdk/eventgrid/Azure.Messaging.EventGrid.SystemEvents/) | -| System.ClientModel | NuGet [1.2.1](https://www.nuget.org/packages/System.ClientModel/1.2.1) | [docs](/dotnet/api/overview/azure/System.ClientModel-readme) | GitHub [1.2.1](https://github.com/Azure/azure-sdk-for-net/tree/System.ClientModel_1.2.1/sdk/core/System.ClientModel/) | +| System.ClientModel | NuGet [1.3.0](https://www.nuget.org/packages/System.ClientModel/1.3.0) | [docs](/dotnet/api/overview/azure/System.ClientModel-readme) | GitHub [1.3.0](https://github.com/Azure/azure-sdk-for-net/tree/System.ClientModel_1.3.0/sdk/core/System.ClientModel/) | | Tables | NuGet [12.10.0](https://www.nuget.org/packages/Azure.Data.Tables/12.10.0) | [docs](/dotnet/api/overview/azure/Data.Tables-readme) | GitHub [12.10.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Data.Tables_12.10.0/sdk/tables/Azure.Data.Tables/) | | Text Analytics | NuGet [5.3.0](https://www.nuget.org/packages/Azure.AI.TextAnalytics/5.3.0) | [docs](/dotnet/api/overview/azure/AI.TextAnalytics-readme) | GitHub [5.3.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.TextAnalytics_5.3.0/sdk/textanalytics/Azure.AI.TextAnalytics/) | | Text Translation | NuGet [1.0.0](https://www.nuget.org/packages/Azure.AI.Translation.Text/1.0.0) | [docs](/dotnet/api/overview/azure/AI.Translation.Text-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.Translation.Text_1.0.0/sdk/translation/Azure.AI.Translation.Text/) | @@ -340,7 +340,7 @@ | Resource Management - Service Fabric | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.ServiceFabric/1.1.0)
NuGet [1.2.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.ServiceFabric/1.2.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ServiceFabric-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceFabric_1.1.0/sdk/servicefabric/Azure.ResourceManager.ServiceFabric/)
GitHub [1.2.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceFabric_1.2.0-beta.1/sdk/servicefabric/Azure.ResourceManager.ServiceFabric/) | | Resource Management - Service Fabric Managed Clusters | NuGet [1.2.0](https://www.nuget.org/packages/Azure.ResourceManager.ServiceFabricManagedClusters/1.2.0)
NuGet [1.3.0-beta.2](https://www.nuget.org/packages/Azure.ResourceManager.ServiceFabricManagedClusters/1.3.0-beta.2) | [docs](/dotnet/api/overview/azure/ResourceManager.ServiceFabricManagedClusters-readme) | GitHub [1.2.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceFabricManagedClusters_1.2.0/sdk/servicefabricmanagedclusters/Azure.ResourceManager.ServiceFabricManagedClusters/)
GitHub [1.3.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceFabricManagedClusters_1.3.0-beta.2/sdk/servicefabricmanagedclusters/Azure.ResourceManager.ServiceFabricManagedClusters/) | | Resource Management - Service Linker | NuGet [1.1.0](https://www.nuget.org/packages/Azure.ResourceManager.ServiceLinker/1.1.0) | [docs](/dotnet/api/overview/azure/ResourceManager.ServiceLinker-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceLinker_1.1.0/sdk/servicelinker/Azure.ResourceManager.ServiceLinker/) | -| Resource Management - Service Networking | NuGet [1.0.1](https://www.nuget.org/packages/Azure.ResourceManager.ServiceNetworking/1.0.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ServiceNetworking-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceNetworking_1.0.1/sdk/servicenetworking/Azure.ResourceManager.ServiceNetworking/) | +| Resource Management - Service Networking | NuGet [1.0.1](https://www.nuget.org/packages/Azure.ResourceManager.ServiceNetworking/1.0.1)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.ServiceNetworking/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.ServiceNetworking-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceNetworking_1.0.1/sdk/servicenetworking/Azure.ResourceManager.ServiceNetworking/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.ServiceNetworking_1.1.0-beta.1/sdk/servicenetworking/Azure.ResourceManager.ServiceNetworking/) | | Resource Management - SignalR | NuGet [1.1.3](https://www.nuget.org/packages/Azure.ResourceManager.SignalR/1.1.3) | [docs](/dotnet/api/overview/azure/ResourceManager.SignalR-readme) | GitHub [1.1.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.SignalR_1.1.3/sdk/signalr/Azure.ResourceManager.SignalR/) | | Resource Management - Sphere | NuGet [1.0.0](https://www.nuget.org/packages/Azure.ResourceManager.Sphere/1.0.0) | [docs](/dotnet/api/overview/azure/ResourceManager.Sphere-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.Sphere_1.0.0/sdk/sphere/Azure.ResourceManager.Sphere/) | | Resource Management - Spring App Discovery | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.ResourceManager.SpringAppDiscovery/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/ResourceManager.SpringAppDiscovery-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.ResourceManager.SpringAppDiscovery_1.0.0-beta.1/sdk/springappdiscovery/Azure.ResourceManager.SpringAppDiscovery/) | diff --git a/docs/azure/sdk/authentication/azure-hosted-apps.md b/docs/azure/sdk/authentication/azure-hosted-apps.md index d10ff44b5e48d..c0d5f4f17938b 100644 --- a/docs/azure/sdk/authentication/azure-hosted-apps.md +++ b/docs/azure/sdk/authentication/azure-hosted-apps.md @@ -3,37 +3,43 @@ title: Authenticate Azure-hosted .NET apps to Azure resources description: Learn how to authenticate apps to Azure services when hosted in an Azure compute service like Azure App Service, Azure Functions, or Azure Virtual Machines. ms.topic: how-to ms.custom: devx-track-dotnet, engagement-fy23, devx-track-azurecli -ms.date: 07/31/2024 +ms.date: 02/06/2025 --- # Authenticate Azure-hosted apps to Azure resources with the Azure SDK for .NET -When an app is hosted in Azure using a service like Azure App Service, Azure Virtual Machines, or Azure Container Instances, the recommended approach to authenticating an app to Azure resources is to use a [managed identity](/entra/identity/managed-identities-azure-resources/overview). +The recommended approach to authenticate an Azure-hosted app to other Azure resources is to use a [managed identity](/entra/identity/managed-identities-azure-resources/overview). This approach is [supported for most Azure services](/entra/identity/managed-identities-azure-resources/managed-identities-status), including apps hosted on Azure App Service, Azure Container Apps, and Azure Virtual Machines. Discover more about different authentication techniques and approaches on the [authentication overview](/dotnet/azure/sdk/authentication) page. In the sections ahead, you'll learn: -A managed identity provides an identity for your app such that it can connect to other Azure resources without the need to use a secret key or other application secret. Internally, Azure knows the identity of your app and what resources it's allowed to connect to. Azure uses this information to automatically obtain Microsoft Entra tokens for the app to allow it to connect to other Azure resources, all without you having to manage any application secrets. +- Essential managed identity concepts +- How to create a managed identity for your app +- How to assign roles to the managed identity +- How to authenticate using the managed identity from your app code -## Managed identity types +## Essential managed identity concepts -There are two types of managed identities: +A managed identity enables your app to securely connect to other Azure resources without the use of secret keys or other application secrets. Internally, Azure tracks the identity and which resources it's allowed to connect to. Azure uses this information to automatically obtain Microsoft Entra tokens for the app to allow it to connect to other Azure resources. -- **System-assigned** - This type of managed identity is provided by and tied directly to an Azure resource. When you enable managed identity on an Azure resource, you get a system-assigned managed identity for that resource. A system-assigned managed identity is tied to the lifecycle of the Azure resource it's associated with. When the resource is deleted, Azure automatically deletes the identity for you. Since all you have to do is enable managed identity for the Azure resource hosting your code, this is the easiest type of managed identity to use. -- **User-assigned** - You may also create a managed identity as a standalone Azure resource. This is most frequently used when your solution has multiple workloads that run on multiple Azure resources that all need to share the same identity and same permissions. For example, if your solution had components that ran on multiple App Service and virtual machine instances that all needed access to the same set of Azure resources, creating and using a user-assigned managed identity across those resources would make sense. +There are two types of managed identities to consider when configuring your hosted app: -This article will cover the steps to enable and use a system-assigned managed identity for an app. If you need to use a user-assigned managed identity, see the article [Manage user-assigned managed identities](/entra/identity/managed-identities-azure-resources/how-manage-user-assigned-managed-identities?pivots=identity-mi-methods-azp) to see how to create a user-assigned managed identity. +- **System-assigned** identities are enabled directly on an Azure resource and are tied to its life cycle. When the resource is deleted, Azure automatically deletes the identity for you. System-assigned identities provide a minimalistic approach to using managed identities. +- **User-assigned** identities are created as standalone Azure resources and offer greater flexibility and capabilities. They are ideal for solutions involving multiple Azure resources that need to share the same identity and permissions. For example, if multiple virtual machines need to access the same set of Azure resources, a user-assigned managed identity provides reusability and optimized management. -## 1 - Enable managed identity in the Azure resource hosting the 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 [Manage user-assigned managed identities](/entra/identity/managed-identities-azure-resources/how-manage-user-assigned-managed-identities?pivots=identity-mi-methods-azp) article for more information. -The first step is to enable managed identity on Azure resource hosting your app. For example, if you're hosting a .NET app using Azure App Service, you need to enable managed identity for the App Service web app that is hosting your app. If you were using a virtual machine to host your app, you would enable your VM to use managed identity. +## Enable a system-assigned managed identity on the Azure hosting resource -You can enable managed identity to be used for an Azure resource using either the Azure portal or the Azure CLI. +To get started using a system-assigned managed identity with your app, enable the identity on the Azure resource hosting your app, such as an Azure App Service, Azure Container App, or Azure Virtual Machine. + +You can enable a system-assigned managed identity for an Azure resource using either the Azure portal or the Azure CLI. ### [Azure portal](#tab/azure-portal) -| Instructions | Screenshot | -|:----------------|-----------:| -| [!INCLUDE [Enable managed identity step 1](<../includes/enable-managed-identity-azure-portal-1.md>)] | :::image type="content" source="../media/enable-managed-identity-azure-portal-1-240px.png" alt-text="A screenshot showing how to use the top search bar in the Azure portal to locate and navigate to an Azure resource." lightbox="../media/enable-managed-identity-azure-portal-1.png"::: | -| [!INCLUDE [Enable managed identity step 2](<../includes/enable-managed-identity-azure-portal-2.md>)] | :::image type="content" source="../media/enable-managed-identity-azure-portal-2-240px.png" alt-text="A screenshot showing the location of the Identity menu item in the left-hand menu for an Azure resource." lightbox="../media/enable-managed-identity-azure-portal-2.png"::: | -| [!INCLUDE [Enable managed identity step 3](<../includes/enable-managed-identity-azure-portal-3.md>)] | :::image type="content" source="../media/enable-managed-identity-azure-portal-3-240px.png" alt-text="A screenshot showing how to enable managed identity for an Azure resource on the resource's Identity page." lightbox="../media/enable-managed-identity-azure-portal-3.png"::: | +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. +1. From the resource's **Overview** page, expand **Settings** and select **Identity** from the navigation. +1. On the **Identity** page, toggle the **Status** slider to **On**. +1. Select **Save** to apply your changes. + + :::image type="content" source="../media/system-assigned-identity-enable.png" alt-text="A screenshot showing how to enable a system-assigned identity on a container app."::: ### [Azure CLI](#tab/azure-cli) @@ -41,9 +47,23 @@ Azure CLI commands can be run in the [Azure Cloud Shell](https://shell.azure.com The Azure CLI commands used to enable managed identity for an Azure resource are of the form `az identity --resource-group --name `. Specific commands for popular Azure services are shown below. -[!INCLUDE [Enable managed identity Azure CLI](<../includes/enable-managed-identity-azure-cli.md>)] +Azure App Service: + +```azurecli +az webapp identity assign \ + --resource-group \ + --name +``` + +Azure Virtual Machine: -The output will look like the following. +```azurecli +az vm identity assign \ + --resource-group \ + --name +``` + +The output resembles the following: ```json { @@ -58,21 +78,35 @@ The `principalId` value is the unique ID of the managed identity. Keep a copy of --- -## 2 - Assign roles to the managed identity +## Assign roles to the managed identity + +Next, determine which roles your app needs and assign those roles to the managed identity. You can assign roles to a managed identity at the following scopes: -Next, determine which roles (permissions) your app needs and assign the managed identity to those roles in Azure. A managed identity can be assigned roles at a resource, resource group, or subscription scope. This example will show how to assign roles at the resource group scope since most applications group all their Azure resources into a single resource group. +- **Resource**: The assigned roles only apply to that specific resource. +- **Resource group**: The assigned roles apply to all resources contained in the resource group. +- **Subscription**: The assigned roles apply to all resources contained in the subscription. + +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](#tab/azure-portal) -| Instructions | Screenshot | -|:----------------|-----------:| -| [!INCLUDE [Assign managed identity to role step 1](<../includes/assign-managed-identity-to-role-azure-portal-1.md>)] | :::image type="content" source="../media/assign-managed-identity-to-role-azure-portal-1-240px.png" alt-text="A screenshot showing how to use the top search bar in the Azure portal to locate and navigate to a resource group in Azure. This is the resource group that you'll assign roles (permissions) to." lightbox="../media/assign-managed-identity-to-role-azure-portal-1.png"::: | -| [!INCLUDE [Assign managed identity to role step 2](<../includes/assign-managed-identity-to-role-azure-portal-2.md>)] | :::image type="content" source="../media/assign-managed-identity-to-role-azure-portal-2-240px.png" alt-text="A screenshot showing the location of the Access control (IAM) menu item in the left-hand menu of an Azure resource group." lightbox="../media/assign-managed-identity-to-role-azure-portal-2.png"::: | -| [!INCLUDE [Assign managed identity to role step 3](<../includes/assign-managed-identity-to-role-azure-portal-3.md>)] | :::image type="content" source="../media/assign-managed-identity-to-role-azure-portal-3-240px.png" alt-text="A screenshot showing how to navigate to the role assignments tab and the location of the button used to add role assignments to a resource group." lightbox="../media/assign-managed-identity-to-role-azure-portal-3.png"::: | -| [!INCLUDE [Assign managed identity to role step 4](<../includes/assign-managed-identity-to-role-azure-portal-4.md>)] | :::image type="content" source="../media/assign-managed-identity-to-role-azure-portal-4-240px.png" alt-text="A screenshot showing how to filter and select role assignments to be added to the resource group." lightbox="../media/assign-managed-identity-to-role-azure-portal-4.png"::: | -| [!INCLUDE [Assign managed identity to role step 5](<../includes/assign-managed-identity-to-role-azure-portal-5.md>)] | :::image type="content" source="../media/assign-managed-identity-to-role-azure-portal-5-240px.png" alt-text="A screenshot showing how to select managed identity as the type of user you want to assign the role (permission) on the add role assignments page." lightbox="../media/assign-managed-identity-to-role-azure-portal-5.png"::: | -| [!INCLUDE [Assign managed identity to role step 6](<../includes/assign-managed-identity-to-role-azure-portal-6.md>)] | :::image type="content" source="../media/assign-managed-identity-to-role-azure-portal-6-240px.png" alt-text="A screenshot showing how to use the select managed identities dialog to filter and select the managed identity to assign the role to." lightbox="../media/assign-managed-identity-to-role-azure-portal-6.png"::: | -| [!INCLUDE [Assign managed identity to role step 7](<../includes/assign-managed-identity-to-role-azure-portal-7.md>)] | :::image type="content" source="../media/assign-managed-identity-to-role-azure-portal-7-240px.png" alt-text="A screenshot of the final add role assignment screen where a user needs to select the Review + Assign button to finalize the role assignment." lightbox="../media/assign-managed-identity-to-role-azure-portal-7.png"::: | +1. Navigate to the **Overview** page of the resource group that contains the app with the system-assigned managed identity. +1. Select **Access control (IAM)** on the left navigation. +1. 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. + + :::image type="content" source="../media/system-assigned-identity-access-control.png" alt-text="A screenshot showing how to access the identity role assignment page."::: + +1. 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. +1. Select the role from the results and then choose **Next** to move to the **Members** tab. +1. For the **Assign access to** option, select **Managed identity**. +1. For the **Members** option, choose **+ Select members** to open the **Select managed identities** panel. +1. 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. + + :::image type="content" source="../media/system-assigned-identity-assign-roles.png" alt-text="A screenshot showing the managed identity assignment process."::: + +1. Select the identity and choose **Select** at the bottom of the panel to continue. +1. Select **Review + assign** at the bottom of the page. +1. On the final **Review + assign** tab, select **Review + assign** to complete the workflow. ### [Azure CLI](#tab/azure-cli) @@ -106,6 +140,6 @@ For information on assigning permissions at the resource or subscription level u --- -## 3 - Implement DefaultAzureCredential in your application +## Implement DefaultAzureCredential in your application [!INCLUDE [Implement DefaultAzureCredential](<../includes/implement-defaultazurecredential.md>)] diff --git a/docs/azure/sdk/authentication/index.md b/docs/azure/sdk/authentication/index.md index 3c62834dadf98..5c906957d3ab4 100644 --- a/docs/azure/sdk/authentication/index.md +++ b/docs/azure/sdk/authentication/index.md @@ -6,7 +6,7 @@ ms.custom: devx-track-dotnet, engagement-fy23 ms.date: 08/02/2024 --- -# How to authenticate .NET apps to Azure services using the Azure Identity library +# Authenticate .NET apps to Azure services using the Azure Identity library overview When an app needs to access an Azure resource, the app must be authenticated to Azure. This is true for all apps, whether deployed to Azure, deployed on-premises, or under development on a local developer workstation. This article describes the recommended approaches to authenticate an app to Azure when using the Azure SDK client libraries. diff --git a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-1.md b/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-1.md deleted file mode 100644 index e1624fba768b3..0000000000000 --- a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-1.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -ms.topic: include -ms.date: 08/05/2024 ---- -Locate the resource group for your app by searching for the resource group name using the search box at the top of the Azure portal.
-
-Navigate to your resource group by selecting the resource group name under the **Resource Groups** heading in the dialog box. diff --git a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-2.md b/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-2.md deleted file mode 100644 index 985e8728a6d1f..0000000000000 --- a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-2.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -ms.topic: include -ms.date: 08/05/2024 ---- -On the page for the resource group, select **Access control (IAM)** from the left-hand menu. diff --git a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-3.md b/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-3.md deleted file mode 100644 index 11ea4bd587fac..0000000000000 --- a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-3.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -ms.topic: include -ms.date: 08/05/2024 ---- -On the **Access control (IAM)** page: - -1. Select the **Role assignments** tab. -1. Select **+ Add** from the top menu and then **Add role assignment** from the resulting drop-down menu. diff --git a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-4.md b/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-4.md deleted file mode 100644 index 42e1053ccaf80..0000000000000 --- a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-4.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -ms.topic: include -ms.date: 08/05/2024 ---- -The **Add role assignment** page lists all of the roles that can be assigned for the resource group. - -1. Use the search box to filter the list to a more manageable size. This example shows how to filter for Storage Blob roles. -1. Select the role that you want to assign. - -Select **Next** to go to the next screen. diff --git a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-5.md b/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-5.md deleted file mode 100644 index c852352372f0a..0000000000000 --- a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-5.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -ms.topic: include -ms.date: 08/05/2024 ---- -The next **Add role assignment** page allows you to specify what user to assign the role to. - -1. Select **Managed identity** under **Assign access to**. -1. Select **+ Select members** under **Members**. - -A dialog box will open on the right-hand side of the Azure portal. diff --git a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-6.md b/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-6.md deleted file mode 100644 index 323a0e7742ce6..0000000000000 --- a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-6.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -ms.topic: include -ms.date: 08/05/2024 ---- -In the **Select managed identities** dialog: - -1. The **Managed identity** dropdown and **Select** text box can be used to filter the list of managed identities in your subscription. In this example, by selecting **App Service**, only managed identities associated with an App Service are displayed. -1. Select the managed identity for the Azure resource hosting your app. - -Select **Select** at the bottom of the dialog to continue. diff --git a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-7.md b/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-7.md deleted file mode 100644 index daf1585f2a026..0000000000000 --- a/docs/azure/sdk/includes/assign-managed-identity-to-role-azure-portal-7.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -ms.topic: include -ms.date: 08/05/2024 ---- -The managed identity will now show as selected on the **Add role assignment** screen.
-
-Select **Review + assign** to go to the final page and then **Review + assign** again to complete the process. diff --git a/docs/azure/sdk/includes/enable-managed-identity-azure-cli.md b/docs/azure/sdk/includes/enable-managed-identity-azure-cli.md deleted file mode 100644 index 499a6f56a8c76..0000000000000 --- a/docs/azure/sdk/includes/enable-managed-identity-azure-cli.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -ms.topic: include -ms.date: 07/31/2024 -ms.custom: devx-track-azurecli ---- -#### [Azure App Service](#tab/azure-app-service) - -```azurecli -az webapp identity assign \ - --resource-group \ - --name -``` - -#### [Azure Virtual Machines](#tab/azure-virtual-machines) - -```azurecli -az vm identity assign \ - --resource-group \ - --name -``` - ---- diff --git a/docs/azure/sdk/includes/enable-managed-identity-azure-portal-1.md b/docs/azure/sdk/includes/enable-managed-identity-azure-portal-1.md deleted file mode 100644 index 386d24bd2dc1b..0000000000000 --- a/docs/azure/sdk/includes/enable-managed-identity-azure-portal-1.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -ms.topic: include -ms.date: 07/31/2024 ---- -Navigate to the resource that hosts your application code in the Azure portal. - -For example, you can type the name of your resource in the search box at the top of the page and navigate to it by selecting it in the dialog box. diff --git a/docs/azure/sdk/includes/enable-managed-identity-azure-portal-2.md b/docs/azure/sdk/includes/enable-managed-identity-azure-portal-2.md deleted file mode 100644 index 9ecfb55203cd6..0000000000000 --- a/docs/azure/sdk/includes/enable-managed-identity-azure-portal-2.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -ms.topic: include -ms.date: 07/31/2024 ---- -On the page for your resource, select the **Identity** menu item from the left-hand menu. - -All Azure resources capable of supporting managed identity will have an **Identity** menu item even though the layout of the menu may vary slightly. diff --git a/docs/azure/sdk/includes/enable-managed-identity-azure-portal-3.md b/docs/azure/sdk/includes/enable-managed-identity-azure-portal-3.md deleted file mode 100644 index 5276e6a4ab194..0000000000000 --- a/docs/azure/sdk/includes/enable-managed-identity-azure-portal-3.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -ms.topic: include -ms.date: 07/31/2024 ---- -On the **Identity** page: - -1. Change the **Status** slider to **On**. -1. Select **Save**. - -A confirmation dialog will verify you want to enable managed identity for your service. Answer **Yes** and managed identity will be enabled for the Azure resource. diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-1-240px.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-1-240px.png deleted file mode 100644 index a8d30d5a18d6b..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-1-240px.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-1.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-1.png deleted file mode 100644 index ea478ec8744b2..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-1.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-2-240px.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-2-240px.png deleted file mode 100644 index b671688cb34db..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-2-240px.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-2.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-2.png deleted file mode 100644 index 736d947fed2ce..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-2.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-3-240px.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-3-240px.png deleted file mode 100644 index 43f33fec34365..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-3-240px.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-3.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-3.png deleted file mode 100644 index 8a54077f36314..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-3.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-4-240px.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-4-240px.png deleted file mode 100644 index 730205ce6d5ce..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-4-240px.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-4.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-4.png deleted file mode 100644 index fee9e0c0ace1b..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-4.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-5-240px.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-5-240px.png deleted file mode 100644 index aded1177bff62..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-5-240px.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-5.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-5.png deleted file mode 100644 index 4725e8d23bc94..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-5.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-6-240px.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-6-240px.png deleted file mode 100644 index 3d513d234d4cd..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-6-240px.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-6.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-6.png deleted file mode 100644 index 9bedf529a8617..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-6.png and /dev/null differ diff --git a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-7-240px.png b/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-7-240px.png deleted file mode 100644 index a47f6bc6a6f4e..0000000000000 Binary files a/docs/azure/sdk/media/assign-managed-identity-to-role-azure-portal-7-240px.png and /dev/null differ diff --git a/docs/azure/sdk/media/enable-managed-identity-azure-portal-1-240px.png b/docs/azure/sdk/media/enable-managed-identity-azure-portal-1-240px.png deleted file mode 100644 index d601a83a4f19f..0000000000000 Binary files a/docs/azure/sdk/media/enable-managed-identity-azure-portal-1-240px.png and /dev/null differ diff --git a/docs/azure/sdk/media/enable-managed-identity-azure-portal-1.png b/docs/azure/sdk/media/enable-managed-identity-azure-portal-1.png deleted file mode 100644 index d818c2dac2278..0000000000000 Binary files a/docs/azure/sdk/media/enable-managed-identity-azure-portal-1.png and /dev/null differ diff --git a/docs/azure/sdk/media/enable-managed-identity-azure-portal-2-240px.png b/docs/azure/sdk/media/enable-managed-identity-azure-portal-2-240px.png deleted file mode 100644 index 4024c86df1717..0000000000000 Binary files a/docs/azure/sdk/media/enable-managed-identity-azure-portal-2-240px.png and /dev/null differ diff --git a/docs/azure/sdk/media/enable-managed-identity-azure-portal-2.png b/docs/azure/sdk/media/enable-managed-identity-azure-portal-2.png deleted file mode 100644 index a3c9a78172970..0000000000000 Binary files a/docs/azure/sdk/media/enable-managed-identity-azure-portal-2.png and /dev/null differ diff --git a/docs/azure/sdk/media/enable-managed-identity-azure-portal-3-240px.png b/docs/azure/sdk/media/enable-managed-identity-azure-portal-3-240px.png deleted file mode 100644 index ee66d720c00fa..0000000000000 Binary files a/docs/azure/sdk/media/enable-managed-identity-azure-portal-3-240px.png and /dev/null differ diff --git a/docs/azure/sdk/media/enable-managed-identity-azure-portal-3.png b/docs/azure/sdk/media/enable-managed-identity-azure-portal-3.png deleted file mode 100644 index d47bc4414096b..0000000000000 Binary files a/docs/azure/sdk/media/enable-managed-identity-azure-portal-3.png and /dev/null differ diff --git a/docs/azure/sdk/media/system-assigned-identity-access-control.png b/docs/azure/sdk/media/system-assigned-identity-access-control.png new file mode 100644 index 0000000000000..702c5ec7d9c23 Binary files /dev/null and b/docs/azure/sdk/media/system-assigned-identity-access-control.png differ diff --git a/docs/azure/sdk/media/system-assigned-identity-assign-roles.png b/docs/azure/sdk/media/system-assigned-identity-assign-roles.png new file mode 100644 index 0000000000000..d3a0809c856f0 Binary files /dev/null and b/docs/azure/sdk/media/system-assigned-identity-assign-roles.png differ diff --git a/docs/azure/sdk/media/system-assigned-identity-enable.png b/docs/azure/sdk/media/system-assigned-identity-enable.png new file mode 100644 index 0000000000000..467429da46cfc Binary files /dev/null and b/docs/azure/sdk/media/system-assigned-identity-enable.png differ diff --git a/docs/core/compatibility/10.0.md b/docs/core/compatibility/10.0.md index 3cfb3b62328eb..fc7e8837b7bf6 100644 --- a/docs/core/compatibility/10.0.md +++ b/docs/core/compatibility/10.0.md @@ -35,9 +35,10 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af ## Cryptography -| Title | Type of change | Introduced version | -|--------------------------------------------------------------------------------------------------------|-------------------|--------------------| -| [X500DistinguishedName validation is stricter](cryptography/10.0/x500distinguishedname-validation.md) | Behavioral change | Preview 1 | +| Title | Type of change | Introduced version | +|------------------------------------------------------------------------------------------------------------|-------------------|--------------------| +| [X500DistinguishedName validation is stricter](cryptography/10.0/x500distinguishedname-validation.md) | Behavioral change | Preview 1 | +| [Environment variable renamed to DOTNET_OPENSSL_VERSION_OVERRIDE](cryptography/10.0/version-override.md) | Behavioral change | Preview 1 | ## Windows Forms diff --git a/docs/core/compatibility/cryptography/10.0/version-override.md b/docs/core/compatibility/cryptography/10.0/version-override.md new file mode 100644 index 0000000000000..7fcb4574d7630 --- /dev/null +++ b/docs/core/compatibility/cryptography/10.0/version-override.md @@ -0,0 +1,38 @@ +--- +title: "Breaking change: Environment variable renamed to DOTNET_OPENSSL_VERSION_OVERRIDE" +description: Learn about the .NET 10 breaking change in .NET cryptography where the environment variable CLR_OPENSSL_VERSION_OVERRIDE was renamed to DOTNET_OPENSSL_VERSION_OVERRIDE. +ms.date: 02/05/2025 +ai-usage: ai-assisted +--- + +# Environment variable renamed to DOTNET_OPENSSL_VERSION_OVERRIDE + +.NET previously supported a configuration-switch environment variable called `CLR_OPENSSL_VERSION_OVERRIDE`, which allowed users to specify the preferred OpenSSL library version for apps running on Linux. In .NET 10, this environment variable has been renamed to `DOTNET_OPENSSL_VERSION_OVERRIDE` to align with the naming convention of other configuration switch environment variables in .NET. + +## Previous behavior + +The `CLR_OPENSSL_VERSION_OVERRIDE` environment variable was used to specify the preferred OpenSSL version to be loaded in the application. + +## New behavior + +The `DOTNET_OPENSSL_VERSION_OVERRIDE` environment variable is used to specify the preferred OpenSSL version to be loaded in the application. + +## Version introduced + +.NET 10 Preview 1 + +## Type of breaking change + +This change is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +This change ensures the environment variable is consistent with the naming convention used for all [.NET environment variables](../../../tools/dotnet-environment-variables.md). + +## Recommended action + +If you have a .NET 10 app that previously used the `CLR_OPENSSL_VERSION_OVERRIDE` environment variable, use `DOTNET_OPENSSL_VERSION_OVERRIDE` instead. + +## Affected APIs + +N/A diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index d512dd2bc91aa..f708acc61586a 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -26,6 +26,8 @@ items: items: - name: X500DistinguishedName validation is stricter href: cryptography/10.0/x500distinguishedname-validation.md + - name: Environment variable renamed to DOTNET_OPENSSL_VERSION_OVERRIDE + href: cryptography/10.0/version-override.md - name: Globalization items: - name: Environment variable renamed to DOTNET_ICU_VERSION_OVERRIDE @@ -1584,6 +1586,8 @@ items: items: - name: X500DistinguishedName validation is stricter href: cryptography/10.0/x500distinguishedname-validation.md + - name: Environment variable renamed to DOTNET_OPENSSL_VERSION_OVERRIDE + href: cryptography/10.0/version-override.md - name: .NET 9 items: - name: SafeEvpPKeyHandle.DuplicateHandle up-refs the handle diff --git a/docs/csharp/language-reference/operators/sizeof.md b/docs/csharp/language-reference/operators/sizeof.md index 0513d391dd672..8ce45f912157a 100644 --- a/docs/csharp/language-reference/operators/sizeof.md +++ b/docs/csharp/language-reference/operators/sizeof.md @@ -1,7 +1,7 @@ --- title: "sizeof operator - determine the storage needs for a type" description: "Learn about the C# `sizeof` operator that returns the memory amount occupied by a variable of a given type." -ms.date: 11/28/2022 +ms.date: 02/06/2025 f1_keywords: - "sizeof_CSharpKeyword" - "sizeof" @@ -10,33 +10,39 @@ helpviewer_keywords: --- # sizeof operator - determine the memory needs for a given type -The `sizeof` operator returns the number of bytes occupied by a variable of a given type. The argument to the `sizeof` operator must be the name of an [unmanaged type](../builtin-types/unmanaged-types.md) or a type parameter that is [constrained](../../programming-guide/generics/constraints-on-type-parameters.md#unmanaged-constraint) to be an unmanaged type. +The `sizeof` operator returns the number of bytes occupied by a variable of a given type. In safe code, the argument to the `sizeof` operator must be the name of an [unmanaged type](../builtin-types/unmanaged-types.md) or a type parameter that is [constrained](../../programming-guide/generics/constraints-on-type-parameters.md#unmanaged-constraint) to be an unmanaged type. Unmanaged types include all numeric types, enum types, and tuple and struct types where all members are unmanaged types. -The `sizeof` operator requires an [unsafe](../keywords/unsafe.md) context. However, the expressions presented in the following table are evaluated in compile time to the corresponding constant values and don't require an unsafe context: +The expressions presented in the following table are evaluated in compile time to the corresponding constant values and don't require an unsafe context: -|Expression|Constant value| -|---------|---------------| -|`sizeof(sbyte)`|1| -|`sizeof(byte)`|1| -|`sizeof(short)`|2| -|`sizeof(ushort)`|2| -|`sizeof(int)`|4| -|`sizeof(uint)`|4| -|`sizeof(long)`|8| -|`sizeof(ulong)`|8| -|`sizeof(char)`|2| -|`sizeof(float)`|4| -|`sizeof(double)`|8| -|`sizeof(decimal)`|16| -|`sizeof(bool)`|1| +| Expression | Constant value | +|-------------------|----------------| +| `sizeof(sbyte)` | 1 | +| `sizeof(byte)` | 1 | +| `sizeof(short)` | 2 | +| `sizeof(ushort)` | 2 | +| `sizeof(int)` | 4 | +| `sizeof(uint)` | 4 | +| `sizeof(long)` | 8 | +| `sizeof(ulong)` | 8 | +| `sizeof(char)` | 2 | +| `sizeof(float)` | 4 | +| `sizeof(double)` | 8 | +| `sizeof(decimal)` | 16 | +| `sizeof(bool)` | 1 | -You also don't need to use an unsafe context when the operand of the `sizeof` operator is the name of an [enum](../builtin-types/enum.md) type. +In unsafe code, the argument to `sizeof` can include pointer types and managed types, including unconstrained type parameters. Examples include `object` and `string`. The following example demonstrates the usage of the `sizeof` operator: -[!code-csharp[sizeof examples](snippets/shared/SizeOfOperator.cs)] +:::code language="csharp" source="./snippets/shared/SizeOfOperator.cs"::: -The `sizeof` operator returns a number of bytes that would be allocated by the common language runtime in managed memory. For [struct](../builtin-types/struct.md) types, that value includes any padding, as the preceding example demonstrates. The result of the `sizeof` operator might differ from the result of the method, which returns the size of a type in *unmanaged* memory. +The `sizeof` operator returns the number of bytes allocated by the common language runtime in managed memory. For [struct](../builtin-types/struct.md) types, that value includes any padding, as the preceding example demonstrates. The result of the `sizeof` operator might differ from the result of the method, which returns the size of a type in *unmanaged* memory. + +In unsafe code, when the argument is a managed type, the `sizeof` operator returns the size of a reference, not the number of bytes allocated for an instance of that type. + +> [!IMPORTANT] +> +> The value returned by `sizeof` can differ from the result of , which returns the size of the type in unmanaged memory. ## C# language specification diff --git a/docs/csharp/language-reference/unsafe-code.md b/docs/csharp/language-reference/unsafe-code.md index 89106a3bdbf1d..f3e4f95b032de 100644 --- a/docs/csharp/language-reference/unsafe-code.md +++ b/docs/csharp/language-reference/unsafe-code.md @@ -1,7 +1,7 @@ --- title: "Unsafe code, pointers to data, and function pointers" description: Learn about unsafe code, pointers, and function pointers. C# requires you to declare an unsafe context to use these features to directly manipulate memory or function pointers (unmanaged delegates). -ms.date: 04/01/2021 +ms.date: 02/06/2025 f1_keywords: - "functionPointer_CSharpKeyword" helpviewer_keywords: @@ -12,32 +12,31 @@ helpviewer_keywords: - "unsafe code [C#]" - "C# language, pointers" - "pointers [C#], about pointers" -ms.assetid: b0fcca10-a92d-4f2a-835b-b0ccae6739ee --- # Unsafe code, pointer types, and function pointers Most of the C# code you write is "verifiably safe code." *Verifiably safe code* means .NET tools can verify that the code is safe. In general, safe code doesn't directly access memory using pointers. It also doesn't allocate raw memory. It creates managed objects instead. -C# supports an [`unsafe`](keywords/unsafe.md) context, in which you may write *unverifiable* code. In an `unsafe` context, code may use pointers, allocate and free blocks of memory, and call methods using function pointers. Unsafe code in C# isn't necessarily dangerous; it's just code whose safety cannot be verified. +C# supports an [`unsafe`](keywords/unsafe.md) context, in which you can write *unverifiable* code. In an `unsafe` context, code can use pointers, allocate and free blocks of memory, and call methods using function pointers. Unsafe code in C# isn't necessarily dangerous; it's just code whose safety can't be verified. Unsafe code has the following properties: - Methods, types, and code blocks can be defined as unsafe. -- In some cases, unsafe code may increase an application's performance by removing array bounds checks. +- In some cases, unsafe code can increase an application's performance by removing array bounds checks. - Unsafe code is required when you call native functions that require pointers. - Using unsafe code introduces security and stability risks. - The code that contains unsafe blocks must be compiled with the [**AllowUnsafeBlocks**](compiler-options/language.md#allowunsafeblocks) compiler option. ## Pointer types -In an unsafe context, a type may be a pointer type, in addition to a value type, or a reference type. A pointer type declaration takes one of the following forms: +In an unsafe context, a type can be a pointer type, in addition to a value type, or a reference type. A pointer type declaration takes one of the following forms: ``` csharp type* identifier; void* identifier; //allowed but not recommended ``` -The type specified before the `*` in a pointer type is called the **referent type**. Only an [unmanaged type](builtin-types/unmanaged-types.md) can be a referent type. +The type specified before the `*` in a pointer type is called the **referent type**. Pointer types don't inherit from [object](builtin-types/reference-types.md) and no conversions exist between pointer types and `object`. Also, boxing and unboxing don't support pointers. However, you can convert between different pointer types and between pointer types and integral types. @@ -48,7 +47,7 @@ int* p1, p2, p3; // Ok int *p1, *p2, *p3; // Invalid in C# ``` -A pointer can't point to a reference or to a [struct](builtin-types/struct.md) that contains references, because an object reference can be garbage collected even if a pointer is pointing to it. The garbage collector doesn't keep track of whether an object is being pointed to by any pointer types. +The garbage collector doesn't keep track of whether an object is being pointed to by any pointer types. If the referrant is an object in the managed heap (including local variables captured by lambda expressions or anonymous delegates), the object must be [pinned](./statements/fixed.md) for as long as the pointer is used. The value of the pointer variable of type `MyType*` is the address of a variable of type `MyType`. The following are examples of pointer type declarations: @@ -66,7 +65,7 @@ int* myVariable; The expression `*myVariable` denotes the `int` variable found at the address contained in `myVariable`. -There are several examples of pointers in the articles on the [`fixed` statement](statements/fixed.md). The following example uses the `unsafe` keyword and the `fixed` statement, and shows how to increment an interior pointer. You can paste this code into the Main function of a console application to run it. These examples must be compiled with the [**AllowUnsafeBlocks**](compiler-options/language.md#allowunsafeblocks) compiler option set. +There are several examples of pointers in the articles on the [`fixed` statement](statements/fixed.md). The following example uses the `unsafe` keyword and the `fixed` statement, and shows how to increment an interior pointer. You can paste this code into the Main function of a console application to run it. These examples must be compiled with the [**AllowUnsafeBlocks**](compiler-options/language.md#allowunsafeblocks) compiler option set. :::code language="csharp" source="snippets/unsafe-code/FixedKeywordExamples.cs" ID="5"::: @@ -74,21 +73,21 @@ You can't apply the indirection operator to a pointer of type `void*`. However, A pointer can be `null`. Applying the indirection operator to a null pointer causes an implementation-defined behavior. -Passing pointers between methods can cause undefined behavior. Consider a method that returns a pointer to a local variable through an `in`, `out`, or `ref` parameter or as the function result. If the pointer was set in a fixed block, the variable to which it points may no longer be fixed. +Passing pointers between methods can cause undefined behavior. Consider a method that returns a pointer to a local variable through an `in`, `out`, or `ref` parameter or as the function result. If the pointer was set in a fixed block, the variable to which it points might no longer be fixed. The following table lists the operators and statements that can operate on pointers in an unsafe context: -|Operator/Statement|Use| -|-------------------------|---------| -|`*`|Performs pointer indirection.| -|`->`|Accesses a member of a struct through a pointer.| -|`[]`|Indexes a pointer.| -|`&`|Obtains the address of a variable.| -|`++` and `--`|Increments and decrements pointers.| -|`+` and `-`|Performs pointer arithmetic.| -|`==`, `!=`, `<`, `>`, `<=`, and `>=`|Compares pointers.| -|[`stackalloc`](operators/stackalloc.md)|Allocates memory on the stack.| -|[`fixed` statement](statements/fixed.md)|Temporarily fixes a variable so that its address may be found.| +| Operator/Statement | Use | +|------------------------------------------|----------------------------------------------------------------| +| `*` | Performs pointer indirection. | +| `->` | Accesses a member of a struct through a pointer. | +| `[]` | Indexes a pointer. | +| `&` | Obtains the address of a variable. | +| `++` and `--` | Increments and decrements pointers. | +| `+` and `-` | Performs pointer arithmetic. | +| `==`, `!=`, `<`, `>`, `<=`, and `>=` | Compares pointers. | +| [`stackalloc`](operators/stackalloc.md) | Allocates memory on the stack. | +| [`fixed` statement](statements/fixed.md) | Temporarily fixes a variable so that its address can be found. | For more information about pointer-related operators, see [Pointer-related operators](operators/pointer-related-operators.md). @@ -116,7 +115,7 @@ A struct can contain an embedded array in unsafe code. In the following example, :::code language="csharp" source="snippets/unsafe-code/FixedKeywordExamples.cs" ID="7"::: -The size of the 128 element `char` array is 256 bytes. Fixed-size [char](builtin-types/char.md) buffers always take 2 bytes per character, regardless of the encoding. This array size is the same even when char buffers are marshalled to API methods or structs with `CharSet = CharSet.Auto` or `CharSet = CharSet.Ansi`. For more information, see . +The size of the 128 element `char` array is 256 bytes. Fixed-size [char](builtin-types/char.md) buffers always take 2 bytes per character, regardless of the encoding. This array size is the same even when char buffers are marshaled to API methods or structs with `CharSet = CharSet.Auto` or `CharSet = CharSet.Ansi`. For more information, see . The preceding example demonstrates accessing `fixed` fields without pinning. Another common fixed-size array is the [bool](builtin-types/bool.md) array. The elements in a `bool` array are always 1 byte in size. `bool` arrays aren't appropriate for creating bit arrays or buffers. @@ -158,7 +157,7 @@ Fixed-size buffers differ from regular arrays in the following ways: The following example uses pointers to copy bytes from one array to another. -This example uses the [unsafe](keywords/unsafe.md) keyword, which enables you to use pointers in the `Copy` method. The [fixed](statements/fixed.md) statement is used to declare pointers to the source and destination arrays. The `fixed` statement *pins* the location of the source and destination arrays in memory so that they will not be moved by garbage collection. The memory blocks for the arrays are unpinned when the `fixed` block is completed. Because the `Copy` method in this example uses the `unsafe` keyword, it must be compiled with the [**AllowUnsafeBlocks**](compiler-options/language.md#allowunsafeblocks) compiler option. +This example uses the [unsafe](keywords/unsafe.md) keyword, which enables you to use pointers in the `Copy` method. The [fixed](statements/fixed.md) statement is used to declare pointers to the source and destination arrays. The `fixed` statement *pins* the location of the source and destination arrays in memory so that garbage collection doesn't move the arrays. The memory blocks for the arrays are unpinned when the `fixed` block is completed. Because the `Copy` method in this example uses the `unsafe` keyword, it must be compiled with the [**AllowUnsafeBlocks**](compiler-options/language.md#allowunsafeblocks) compiler option. This example accesses the elements of both arrays using indices rather than a second unmanaged pointer. The declaration of the `pSource` and `pTarget` pointers pins the arrays. @@ -168,7 +167,7 @@ This example accesses the elements of both arrays using indices rather than a se C# provides [`delegate`](builtin-types/reference-types.md#the-delegate-type) types to define safe function pointer objects. Invoking a delegate involves instantiating a type derived from and making a virtual method call to its `Invoke` method. This virtual call uses the `callvirt` IL instruction. In performance critical code paths, using the `calli` IL instruction is more efficient. -You can define a function pointer using the `delegate*` syntax. The compiler will call the function using the `calli` instruction rather than instantiating a `delegate` object and calling `Invoke`. The following code declares two methods that use a `delegate` or a `delegate*` to combine two objects of the same type. The first method uses a delegate type. The second method uses a `delegate*` declaration with the same parameters and return type: +You can define a function pointer using the `delegate*` syntax. The compiler calls the function using the `calli` instruction rather than instantiating a `delegate` object and calling `Invoke`. The following code declares two methods that use a `delegate` or a `delegate*` to combine two objects of the same type. The first method uses a delegate type. The second method uses a `delegate*` declaration with the same parameters and return type: :::code language="csharp" source="snippets/unsafe-code/FunctionPointers.cs" ID="UseDelegateOrPointer"::: @@ -184,7 +183,7 @@ The preceding code illustrates several of the rules on the function accessed as The syntax has parallels with declaring `delegate` types and using pointers. The `*` suffix on `delegate` indicates the declaration is a *function pointer*. The `&` when assigning a method group to a function pointer indicates the operation takes the address of the method. -You can specify the calling convention for a `delegate*` using the keywords `managed` and `unmanaged`. In addition, for `unmanaged` function pointers, you can specify the calling convention. The following declarations show examples of each. The first declaration uses the `managed` calling convention, which is the default. The next four use an `unmanaged` calling convention. Each specifies one of the ECMA 335 calling conventions: `Cdecl`, `Stdcall`, `Fastcall`, or `Thiscall`. The last declaration uses the `unmanaged` calling convention, instructing the CLR to pick the default calling convention for the platform. The CLR will choose the calling convention at run time. +You can specify the calling convention for a `delegate*` using the keywords `managed` and `unmanaged`. In addition, for `unmanaged` function pointers, you can specify the calling convention. The following declarations show examples of each. The first declaration uses the `managed` calling convention, which is the default. The next four use an `unmanaged` calling convention. Each specifies one of the ECMA 335 calling conventions: `Cdecl`, `Stdcall`, `Fastcall`, or `Thiscall`. The last declaration uses the `unmanaged` calling convention, instructing the CLR to pick the default calling convention for the platform. The CLR chooses the calling convention at run time. :::code language="csharp" source="snippets/unsafe-code/FunctionPointers.cs" ID="UnmanagedFunctionPointers"::: diff --git a/docs/standard/attributes/retrieving-information-stored-in-attributes.md b/docs/standard/attributes/retrieving-information-stored-in-attributes.md index 48c8942845941..f178f234fbb17 100644 --- a/docs/standard/attributes/retrieving-information-stored-in-attributes.md +++ b/docs/standard/attributes/retrieving-information-stored-in-attributes.md @@ -1,6 +1,6 @@ --- title: "Retrieving Information Stored in Attributes" -description: Learn to retrieve information stored in attributes, such as for an attribute instance, many instances for the same scope, & many instances for different scopes. +description: Learn to retrieve information stored in attributes, including for an attribute instance, multiple instances for the same scope, multiple instances for different scopes, and attributes applied to class members. ms.date: "08/05/2022" ms.custom: devdivchpfy22 dev_langs: @@ -82,7 +82,17 @@ The attribute was not found. If no instances of the `DeveloperAttribute` are found on the method level or class level, the `GetAttribute` method notifies the user that no attributes were found and displays the name of the method or class that doesn't contain the attribute. If an attribute is found, the console displays the `Name`, `Level`, and `Reviewed` fields. - You can use the members of the class to get the individual methods and members in the passed class. This example first queries the `Type` object to get attribute information for the class level. Next, it uses to place instances of all methods into an array of objects to retrieve attribute information for the method level. You can also use the method to check for attributes on the property level or to check for attributes on the constructor level. + You can use the members of the class to get the individual methods and members in the passed class. This example first queries the `Type` object to get attribute information for the class level. Next, it uses to place instances of all methods into an array of objects to retrieve attribute information for the method level. You can also use the method to check for attributes on the property level or to check for attributes on the constructor level. + +## Retrieving Attributes from Class Members + +In addition to retrieving attributes at the class level, attributes can also be applied to individual members such as methods, properties, and fields. The `GetCustomAttribute` and `GetCustomAttributes` methods can be used to retrieve these attributes. + +### Example + +The following example demonstrates how to retrieve an attribute applied to a method: + +[!code-csharp[Conceptual.Attributes.Usage#21](../../../samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/cs/source4.cs#21)] ## See also diff --git a/samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/conceptualAttrUsage.csproj b/samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/conceptualAttrUsage.csproj new file mode 100644 index 0000000000000..759468c67814d --- /dev/null +++ b/samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/conceptualAttrUsage.csproj @@ -0,0 +1,12 @@ + + + + Exe + net8.0 + enable + enable + AttributeRetrieval + false + + + diff --git a/samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/cs/makefile b/samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/cs/makefile index cd2eff1878c69..24bc3cdc22062 100644 --- a/samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/cs/makefile +++ b/samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/cs/makefile @@ -1,4 +1,4 @@ -all: source1.exe source2.dll source3.exe +all: source1.exe source2.dll source3.exe source4.exe source1.exe: source1.cs csc source1.cs @@ -9,3 +9,5 @@ source2.dll: source2.cs source3.exe: source2.dll source3.cs csc /r:source2.dll source3.cs +source4.exe: source4.cs + csc source4.cs diff --git a/samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/cs/source4.cs b/samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/cs/source4.cs new file mode 100644 index 0000000000000..53a60dd093c72 --- /dev/null +++ b/samples/snippets/csharp/VS_Snippets_CLR/conceptual.attributes.usage/cs/source4.cs @@ -0,0 +1,40 @@ +// +using System; +using System.Reflection; + +[AttributeUsage(AttributeTargets.Method)] +public class MyAttribute : Attribute +{ + public string Description { get; } + public MyAttribute(string description) { Description = description; } +} + +public class MyClass +{ + [MyAttribute("This is a sample method.")] + public void MyMethod() { } +} + +class AttributeRetrieval +{ + public static void Main() + { + // Create an instance of MyClass + MyClass myClass = new MyClass(); + + // Retrieve the method information for MyMethod + MethodInfo methodInfo = typeof(MyClass).GetMethod("MyMethod"); + MyAttribute attribute = (MyAttribute)Attribute.GetCustomAttribute(methodInfo, typeof(MyAttribute)); + + if (attribute != null) + { + // Print the description of the method attribute + Console.WriteLine("Method Attribute: {0}", attribute.Description); + } + else + { + Console.WriteLine("Attribute not found."); + } + } +} +//