-
Notifications
You must be signed in to change notification settings - Fork 6.1k
ASP.NET Core best practices and guidance #42881
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 19 commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
10dded8
ASP.NET Core guidance
alexwolfmsft ee2cb3f
draft
alexwolfmsft ef9c9eb
updates
alexwolfmsft d4ebcdb
title update
alexwolfmsft 695a30c
title
alexwolfmsft 6987420
progress
alexwolfmsft 45b9c21
sample code
alexwolfmsft 8c6bbf2
progress
alexwolfmsft 5a2d54e
fixes
alexwolfmsft c61094f
fixes
alexwolfmsft 48b9d82
added language
alexwolfmsft 53bd17c
progress
alexwolfmsft 1ac7f25
line numbers
alexwolfmsft a2e886f
fix lines
alexwolfmsft 5c9cbee
updates
alexwolfmsft 9ee494a
Fixes
alexwolfmsft 530a569
tweaks
alexwolfmsft cc7d963
tweak
alexwolfmsft 4130ee5
links
alexwolfmsft 5b17c7f
Apply suggestions from code review
alexwolfmsft bd826ae
updates
alexwolfmsft b8b9e85
fix toc
alexwolfmsft d90b999
fix
alexwolfmsft 568fb75
Apply suggestions from code review
alexwolfmsft 447284f
udpate auth instructions
alexwolfmsft ffc02b7
Apply suggestions from code review
alexwolfmsft affa4e7
fixes
alexwolfmsft e8762bb
Merge branch 'aspnetcore-guidance' of https://github.com/alexwolfmsft…
alexwolfmsft 5f9dbb0
fixes
alexwolfmsft 0351996
Apply suggestions from code review
alexwolfmsft 86221c2
Apply suggestions from code review
alexwolfmsft 033832c
Update aspnetcore-guidance.md
alexwolfmsft ef78dea
Apply suggestions from code review
alexwolfmsft c830fe4
update to .NET 9
alexwolfmsft f4f995d
package updates
alexwolfmsft f51d348
fix build
alexwolfmsft 270bd4d
fix link
alexwolfmsft 5f7f61e
fix lines
alexwolfmsft db1fd8a
fix lines
alexwolfmsft 80e628e
line number
alexwolfmsft df32fae
Apply suggestions from code review
alexwolfmsft File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| --- | ||
| title: Best practices for using the Azure SDK with ASP.NET Core | ||
| description: Learn best practices and the steps to properly implement the Azure SDK for .NET in your ASP.NET Core apps. | ||
| ms.topic: conceptual | ||
| ms.custom: devx-track-dotnet | ||
| ms.date: 10/22/2024 | ||
| --- | ||
|
|
||
| # Implement the Azure SDK for .NET in ASP.NET Core apps | ||
|
|
||
| The Azure SDK for .NET enables ASP.NET Core apps to integrate with many different Azure services. In this article, you'll learn best practices and the steps to implement the Azure SDK for .NET in your ASP.NET Core apps. You'll learn how to: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| - Register services for dependency injection. | ||
alexwolfmsft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - Authenticate to Azure without using passwords or secrets. | ||
| - Implement centralized, standardized configuration. | ||
| - Configure common web app concerns such as logging and retries. | ||
|
|
||
| ## Explore common Azure SDK client libraries | ||
|
|
||
| ASP.NET Core apps that connect to Azure services generally depend on the following client libraries: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| - [Microsoft.Extensions.Azure](https://www.nuget.org/packages/Microsoft.Extensions.Azure) provides helper methods to properly register your services and handles various concerns for you, such as setting up logging, handling service lifetimes, and authentication credential management. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - [Azure.Identity](https://www.nuget.org/packages/Azure.Identity) enables Microsoft Entra ID authentication support across the Azure SDK. It provides a set of [TokenCredential](/dotnet/api/azure.core.tokencredential?view=azure-dotnet) implementations to construct Azure SDK clients that support Microsoft Entra authentication. | ||
| - `Azure.<service-namespace>` libraries such as [Azure.Storage.Blob](https://www.nuget.org/packages/Azure.Storage.Blobs) and [Azure.Messaging.ServiceBus](https://www.nuget.org/packages/Azure.Messaging.ServiceBus) provide service clients and other types to help you connect to and consume specific Azure services. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| In the sections ahead, you'll explore how to implement these libraries in an ASP.NET Core app. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Register service clients | ||
|
|
||
| The Azure SDK for .NET provides service clients to connect your app to Azure services such as Azure Blob Storage and Azure Key Vault. Register these services with the dependency container in the `Program.cs` file of your app to make them available to your app using Dependency Injection. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Complete the following steps to register the services you need: | ||
|
|
||
| 1. Add the [Microsoft.Extensions.Azure](https://www.nuget.org/packages/Microsoft.Extensions.Azure) package: | ||
|
|
||
| ```dotnetcli | ||
| dotnet add package Microsoft.Extensions.Azure | ||
| ``` | ||
|
|
||
| 2. Add the relevant `Azure.*` service packages: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```dotnetcli | ||
| dotnet add package Azure.Security.KeyVault.Secrets | ||
| dotnet add package Azure.Storage.Blobs | ||
| dotnet add package Azure.Messaging.ServiceBus | ||
| ``` | ||
|
|
||
| 3. In the `Program.cs` file of your app, invoke the `AddAzureClients` extension method from the `Microsoft.Extensions.Azure` library to register a client for each service. Some services use additional subclients, which you can also register for dependency injection. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| :::code language="csharp" source="snippets/aspnetcore-guidance/BlazorSample/Program.cs" range="11-30" highlight="4-7,11-16"::: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| 4. Inject the registered services into your ASP.NET Core app components, services, or API endpoint: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| <!-- markdownlint-disable MD023 --> | ||
| ## [Minimal API](#tab/api) | ||
|
|
||
| :::code language="csharp" source="snippets/aspnetcore-guidance/MinApiSample/Program.cs" range="44-59" highlight="1,4,5"::: | ||
|
|
||
| <!-- markdownlint-disable MD023 --> | ||
| ## [Blazor](#tab/blazor) | ||
|
|
||
| :::code language="cshtml" source="snippets/aspnetcore-guidance/BlazorSample/Components/Pages/Home.razor" range="1-28" highlight="5,21"::: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| --- | ||
|
|
||
| Visit the [Dependency injection with the Azure SDK for .NET](https://review.learn.microsoft.com/en-us/dotnet/azure/sdk/dependency-injection) page for more detailed guidance. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Authenticate using Microsoft Entra ID | ||
|
|
||
| [Microsoft Entra ID](/entra/fundamentals/whatis) is the recommended approach to authenticate requests to Azure services. This identity service supports [role-based access control (RBAC)](/azure/role-based-access-control/overview) to manage access to Azure resources based on a user's Entra ID account and assigned roles. | ||
|
|
||
| Use the [Azure.Identity](/dotnet/api/overview/azure/identity-readme) client library to implement secretless connections to Azure services in your code with Microsoft Entra ID. The Azure Identity client library provides tools such as [`DefaultAzureCredential`](/dotnet/api/azure.identity.defaultazurecredential) to simplify configuring secure connections. `DefaultAzureCredential` supports multiple authentication methods and determines which method should be used at runtime. This approach enables your app to use different authentication methods in different environments (local vs. production) without implementing environment-specific code. Visit the [Authentication](/dotnet/azure/sdk/authentication) section of the Azure SDK for .NET docs for more details on these topics. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| > [!NOTE] | ||
| > Many Azure services also allow you to authorize requests using secrets keys. However, this approach should be used with caution. Developers must be diligent to never expose the access key in an unsecure location. Anyone who has the access key is able to authorize requests against the service and data. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Consider the following use of `DefaultAzureCredential`: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| :::code language="csharp" source="snippets/aspnetcore-guidance/BlazorSample/Program.cs" range="11-30" highlight="19"::: | ||
|
|
||
| In the preceding code, the `UseCredential()` method accepts an instance of `DefaultAzureCredential` to reuse across your registered services. `DefaultAzureCredential` discovers available credentials in the current environment and use them to connect to Azure services. The complete order and locations that `DefaultAzureCredential` looks for credentials lives in the [`Azure Identity library overview`](/dotnet/api/overview/azure/Identity-readme#defaultazurecredential). | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| For example, when you run the app locally, `DefaultAzureCredential` discovers and uses credentials from the following developer tools: | ||
|
|
||
| - Environment variables | ||
| - Visual Studio | ||
| - Azure CLI | ||
| - Azure PowerShell | ||
| - Azure Developer CLI | ||
|
|
||
| `DefaultAzureCredential` also discovers credentials after you deploy your app from the following: | ||
|
|
||
| - Environment variables | ||
| - Workload identity | ||
| - Managed identity | ||
|
|
||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ## Apply configurations | ||
|
|
||
| Azure SDK service clients support configurations to change their default behaviors. There are two ways to configure service clients: | ||
|
|
||
| - [Configuration files](/dotnet/core/extensions/configuration-providers#json-configuration-provider) are generally the recommended approach because they simplify app deployments between environments and reduce hard coded values. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - Inline code configurations can be applied when you register the service client. For example, in the [Register clients and subclients](#register-service-clients) section, you explicitly passed the URI variables to the client constructors. | ||
|
|
||
| Complete the steps in the following sections to update your app to use JSON file configuration for the appropriate environments. Use the `appsettings.Development.json` file for development settings and the `appsettings.Production.json` file for production environment settings. You can add any properties from the [`ClientOptions`](/dotnet/api/azure.core.clientoptions) class to the JSON file. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### Configure registered services | ||
|
|
||
| 1. Update the `appsettings.<environment>.json` file in your app with the highlighted service configurations: | ||
|
|
||
| :::code language="json" source="snippets/aspnetcore-guidance/MinApiSample/appsettings.Development.json" highlight="19-27"::: | ||
|
|
||
| In the preceding JSON sample: | ||
|
|
||
| - The top-level key names, `KeyVault`, `ServiceBus`, and `Storage`, are arbitrary names used to reference the config sections from your code. All other key names map to specific service options, and JSON serialization is performed in a case-insensitive manner. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - The `KeyVault:VaultUri`, `ServiceBus:Namespace`, and `Storage:ServiceUri` key values map to the arguments of the <xref:Azure.Security.KeyVault.Secrets.SecretClient.%23ctor(System.Uri,Azure.Core.TokenCredential,Azure.Security.KeyVault.Secrets.SecretClientOptions)?displayProperty=name>, <xref:Azure.Messaging.ServiceBus.ServiceBusClient.%23ctor(System.String)?displayProperty=name>, and <xref:Azure.Storage.Blobs.BlobServiceClient.%23ctor(System.Uri,Azure.Core.TokenCredential,Azure.Storage.Blobs.BlobClientOptions)?displayProperty=name> constructor overloads, respectively. The `TokenCredential` variants of the constructors are used because a default `TokenCredential` is set via the <xref:Microsoft.Extensions.Azure.AzureClientFactoryBuilder.UseCredential(Azure.Core.TokenCredential)?displayProperty=name> method call. | ||
alexwolfmsft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| 1. Update the the `Program.cs` file to retrieve the JSON file configurations using `IConfiguration` and pass them into your service registrations: | ||
|
|
||
| :::code language="csharp" source="snippets/aspnetcore-guidance/MinApiSample/Program.cs" range="13-31" highlight="4-5,7-8,11-12"::: | ||
|
|
||
| ### Configure Azure defaults and retries | ||
|
|
||
| You may want to change default Azure client configurations globally or for a specific service client. For example, you may want different retry settings or to use a different service API version. You can set the retry settings globally or on a per-service basis. | ||
|
|
||
| 1. Update your configuration file to set default Azure settings, such as a new default retry policy: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| :::code language="json" source="snippets/aspnetcore-guidance/MinApiSample/appsettings.Development.json" highlight="9-18"::: | ||
|
|
||
| 2. In the `Program.cs` file, the `ConfigureDefaults` extension method `AddAzureClients` retrieves the default settings and applies them to your services: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| :::code language="csharp" source="snippets/aspnetcore-guidance/MinApiSample/Program.cs" range="13-31" highlight="17-18"::: | ||
|
|
||
| ## Configure logging | ||
|
|
||
| The Azure SDK for .NET client libraries can log client library operations to monitor requests and responses to Azure services. When you register an Azure SDK client using the <xref:Microsoft.Extensions.Azure.AzureClientServiceCollectionExtensions.AddAzureClients%2A> extension method, the <xref:Microsoft.Extensions.Azure.AzureEventSourceLogForwarder> is registered with the dependency injection container. This service forwards log messages from Azure SDK event sources to <xref:Microsoft.Extensions.Logging.ILoggerFactory> to enables you to use the standard ASP.NET Core logging configuration for logging. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| The following table depicts how the Azure SDK for .NET `EventLevel` maps to the ASP.NET Core `LogLevel`. Visit the [Logging with the Azure SDK for .NET](/dotnet/azure/sdk/logging) page to learn more. | ||
|
|
||
| | Azure SDK `EventLevel` | ASP.NET Core `LogLevel` | | ||
| |------------------------|-------------------------| | ||
| | `Critical` | `Critical` | | ||
| | `Error` | `Error` | | ||
| | `Informational` | `Information` | | ||
| | `Warning` | `Warning` | | ||
| | `Verbose` | `Debug` | | ||
| | `LogAlways` | `Information` | | ||
|
|
||
| You can change default log levels and other settings using the same JSON configurations outlined in the [configure authentication](#authenticate-using-microsoft-entra-id) section. For example, toggle a the `ServiceBusClient` log level to `Debug` by setting the `Logging:LogLevel:Azure.Messaging.ServiceBus` key as follows: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| :::code language="json" source="snippets/aspnetcore-guidance/MinApiSample/appsettings.Development.json" highlight="2-8"::: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
16 changes: 16 additions & 0 deletions
16
docs/azure/sdk/snippets/aspnetcore-guidance/BlazorSample/BlazorSample.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>net8.0</TargetFramework> | ||
| <Nullable>enable</Nullable> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Azure.Messaging.ServiceBus" Version="7.18.2" /> | ||
| <PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.7.0" /> | ||
| <PackageReference Include="Azure.Storage.Blobs" Version="12.22.2" /> | ||
| <PackageReference Include="Microsoft.Extensions.Azure" Version="1.7.6" /> | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| </ItemGroup> | ||
|
|
||
| </Project> | ||
20 changes: 20 additions & 0 deletions
20
docs/azure/sdk/snippets/aspnetcore-guidance/BlazorSample/Components/App.razor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
|
|
||
| <head> | ||
| <meta charset="utf-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <base href="/" /> | ||
| <link rel="stylesheet" href="bootstrap/bootstrap.min.css" /> | ||
| <link rel="stylesheet" href="app.css" /> | ||
| <link rel="stylesheet" href="AspNetCoreAzureSDK.styles.css" /> | ||
| <link rel="icon" type="image/png" href="favicon.png" /> | ||
| <HeadOutlet /> | ||
| </head> | ||
|
|
||
| <body> | ||
| <Routes /> | ||
| <script src="_framework/blazor.web.js"></script> | ||
| </body> | ||
|
|
||
| </html> |
17 changes: 17 additions & 0 deletions
17
docs/azure/sdk/snippets/aspnetcore-guidance/BlazorSample/Components/Layout/MainLayout.razor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| @inherits LayoutComponentBase | ||
|
|
||
| <div class="page"> | ||
| <div class="sidebar"> | ||
| <NavMenu /> | ||
| </div> | ||
|
|
||
| <main> | ||
| <div class="top-row px-4"> | ||
| <a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a> | ||
| </div> | ||
|
|
||
| <article class="content px-4"> | ||
| @Body | ||
| </article> | ||
| </main> | ||
| </div> |
96 changes: 96 additions & 0 deletions
96
...zure/sdk/snippets/aspnetcore-guidance/BlazorSample/Components/Layout/MainLayout.razor.css
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| .page { | ||
| position: relative; | ||
| display: flex; | ||
| flex-direction: column; | ||
| } | ||
|
|
||
| main { | ||
| flex: 1; | ||
| } | ||
|
|
||
| .sidebar { | ||
| background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); | ||
| } | ||
|
|
||
| .top-row { | ||
| background-color: #f7f7f7; | ||
| border-bottom: 1px solid #d6d5d5; | ||
| justify-content: flex-end; | ||
| height: 3.5rem; | ||
| display: flex; | ||
| align-items: center; | ||
| } | ||
|
|
||
| .top-row ::deep a, .top-row ::deep .btn-link { | ||
| white-space: nowrap; | ||
| margin-left: 1.5rem; | ||
| text-decoration: none; | ||
| } | ||
|
|
||
| .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { | ||
| text-decoration: underline; | ||
| } | ||
|
|
||
| .top-row ::deep a:first-child { | ||
| overflow: hidden; | ||
| text-overflow: ellipsis; | ||
| } | ||
|
|
||
| @media (max-width: 640.98px) { | ||
| .top-row { | ||
| justify-content: space-between; | ||
| } | ||
|
|
||
| .top-row ::deep a, .top-row ::deep .btn-link { | ||
| margin-left: 0; | ||
| } | ||
| } | ||
|
|
||
| @media (min-width: 641px) { | ||
| .page { | ||
| flex-direction: row; | ||
| } | ||
|
|
||
| .sidebar { | ||
| width: 250px; | ||
| height: 100vh; | ||
| position: sticky; | ||
| top: 0; | ||
| } | ||
|
|
||
| .top-row { | ||
| position: sticky; | ||
| top: 0; | ||
| z-index: 1; | ||
| } | ||
|
|
||
| .top-row.auth ::deep a:first-child { | ||
| flex: 1; | ||
| text-align: right; | ||
| width: 0; | ||
| } | ||
|
|
||
| .top-row, article { | ||
| padding-left: 2rem !important; | ||
| padding-right: 1.5rem !important; | ||
| } | ||
| } | ||
|
|
||
| #blazor-error-ui { | ||
| background: lightyellow; | ||
| bottom: 0; | ||
| box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); | ||
| display: none; | ||
| left: 0; | ||
| padding: 0.6rem 1.25rem 0.7rem 1.25rem; | ||
| position: fixed; | ||
| width: 100%; | ||
| z-index: 1000; | ||
| } | ||
|
|
||
| #blazor-error-ui .dismiss { | ||
| cursor: pointer; | ||
| position: absolute; | ||
| right: 0.75rem; | ||
| top: 0.5rem; | ||
| } |
24 changes: 24 additions & 0 deletions
24
docs/azure/sdk/snippets/aspnetcore-guidance/BlazorSample/Components/Layout/NavMenu.razor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <div class="top-row ps-3 navbar navbar-dark"> | ||
| <div class="container-fluid"> | ||
| <a class="navbar-brand" href="">AspNetCoreAzureSDK</a> | ||
| </div> | ||
| </div> | ||
|
|
||
| <input type="checkbox" title="Navigation menu" class="navbar-toggler" /> | ||
|
|
||
| <div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()"> | ||
| <nav class="flex-column"> | ||
| <div class="nav-item px-3"> | ||
| <NavLink class="nav-link" href="" Match="NavLinkMatch.All"> | ||
| <span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home | ||
| </NavLink> | ||
| </div> | ||
|
|
||
| <div class="nav-item px-3"> | ||
| <NavLink class="nav-link" href="weather"> | ||
| <span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather | ||
| </NavLink> | ||
| </div> | ||
| </nav> | ||
| </div> | ||
|
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.