Skip to content

Commit 90442e4

Browse files
authored
Merge pull request #36790 from dotnet/main
Merge to Live
2 parents 875fb04 + e2254ea commit 90442e4

3 files changed

Lines changed: 97 additions & 11 deletions

File tree

aspnetcore/blazor/fundamentals/signalr.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,76 @@ protected override async Task OnInitializedAsync()
17991799

18001800
In the preceding code, `NavManager` is a <xref:Microsoft.AspNetCore.Components.NavigationManager>, and `AuthenticationStateProvider` is an <xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider> service instance ([`AuthenticationStateProvider` documentation](xref:blazor/security/authentication-state)).
18011801

1802+
## Configure the hub URL endpoint for a loopback connection
1803+
1804+
*This section only applies to server-side Blazor apps.*
1805+
1806+
If HTTP requests in a server-side Blazor app are failing to connect to itself when using <xref:Microsoft.AspNetCore.Components.NavigationManager.ToAbsoluteUri%2A?displayProperty=nameWithType>, you might have a load balancer or proxy that isn't expecting requests from the backend server. In this scenario, you can try to change the hub URL that the client is using to connect directly to the backend server.
1807+
1808+
The following example:
1809+
1810+
* Configures the hub URL using <xref:System.UriBuilder> and passes it to <xref:Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl%2A>.
1811+
* Sets the URI based on the server's address (<xref:Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>) and machine name (<xref:System.Environment.MachineName%2A>).
1812+
1813+
```razor
1814+
@using System.Net
1815+
@using System.Net.Sockets
1816+
@using Microsoft.AspNetCore.Hosting.Server
1817+
@using Microsoft.AspNetCore.Hosting.Server.Features
1818+
@using Microsoft.AspNetCore.SignalR.Client
1819+
@inject IHostEnvironment Environment
1820+
@inject IServer Server
1821+
1822+
...
1823+
1824+
@code {
1825+
private HubConnection? hubConnection;
1826+
1827+
protected override async Task OnInitializedAsync()
1828+
{
1829+
var serverAddress = Server.Features
1830+
.Get<IServerAddressesFeature>()?
1831+
.Addresses
1832+
.FirstOrDefault(a => a.StartsWith("http://") || a.StartsWith("https://"));
1833+
1834+
if (serverAddress is null)
1835+
{
1836+
throw new InvalidOperationException("No server address available.");
1837+
}
1838+
1839+
var uri = new UriBuilder(serverAddress + "/chathub");
1840+
1841+
// If Kestrel is bound to a wildcard, substitute a real IP
1842+
if (uri.Host is "0.0.0.0" or "[::]" or "+" or "*")
1843+
{
1844+
var addresses = await Dns.GetHostAddressesAsync(
1845+
System.Environment.MachineName);
1846+
var ip = addresses.FirstOrDefault(a =>
1847+
a.AddressFamily == AddressFamily.InterNetwork
1848+
&& !IPAddress.IsLoopback(a));
1849+
1850+
if (ip is null)
1851+
{
1852+
throw new InvalidOperationException("No suitable IP address.");
1853+
}
1854+
1855+
uri.Host = ip.ToString();
1856+
}
1857+
1858+
hubConnection = new HubConnectionBuilder()
1859+
.WithUrl(uri.Uri)
1860+
.Build();
1861+
1862+
hubConnection.On<ChatMessage>("ReceiveMessage", (message) =>
1863+
{
1864+
...
1865+
});
1866+
1867+
await hubConnection.StartAsync();
1868+
}
1869+
}
1870+
```
1871+
18021872
## Additional server-side resources
18031873

18041874
* [Server-side host and deployment guidance: SignalR configuration](xref:blazor/host-and-deploy/server/index#signalr-configuration)

aspnetcore/blazor/project-structure.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,15 @@ The `Components` folder of the server project holds the app's server-side Razor
6363

6464
The `Components/Pages` folder of the server project contains the app's routable server-side Razor components. The route for each page is specified using the [`@page`](xref:mvc/views/razor#page) directive.
6565

66-
moniker range=">= aspnetcore-10.0"
66+
:::moniker-end
67+
68+
:::moniker range=">= aspnetcore-10.0"
6769

6870
The `NotFound` component (`NotFound.razor`) implements a Not Found page to display when content isn't found for a request path. For more information, see <xref:blazor/fundamentals/navigation#not-found-responses>.
6971

70-
moniker-end
72+
:::moniker-end
73+
74+
:::moniker range=">= aspnetcore-8.0"
7175

7276
The `App` component (`App.razor`) is the root component of the app with HTML `<head>` markup, the `Routes` component, and the Blazor `<script>` tag. The root component is the first component that the app loads.
7377

@@ -316,28 +320,28 @@ Project structure:
316320
* `NavMenu` component (`NavMenu.razor`): Implements sidebar navigation. Includes the [`NavLink` component](xref:blazor/fundamentals/navigation#navlink-component) (<xref:Microsoft.AspNetCore.Components.Routing.NavLink>), which renders navigation links to other Razor components. The <xref:Microsoft.AspNetCore.Components.Routing.NavLink> component automatically indicates a selected state when its component is loaded, which helps the user understand which component is currently displayed.
317321
* `NavMenu.razor.css`: Stylesheet for the app's navigation menu.
318322

319-
moniker-end
323+
:::moniker-end
320324

321-
moniker range=">= aspnetcore-10.0"
325+
:::moniker range=">= aspnetcore-10.0"
322326

323327
* `Pages` folder: Contains the Blazor app's routable Razor components (`.razor`). The route for each page is specified using the [`@page`](xref:mvc/views/razor#page) directive. The template includes the following components:
324328
* `Counter` component (`Counter.razor`): Implements the Counter page.
325329
* `Index` component (`Index.razor`): Implements the Home page.
326330
* `Weather` component (`Weather.razor`): Implements the Weather page.
327331
* `NotFound` component (`NotFound.razor`): Implements a Not Found page to display when content isn't found for a request path. For more information, see <xref:blazor/fundamentals/navigation#not-found-responses>.
328332

329-
moniker-end
333+
:::moniker-end
330334

331-
moniker range=">= aspnetcore-8.0 < aspnetcore-10.0"
335+
:::moniker range=">= aspnetcore-8.0 < aspnetcore-10.0"
332336

333337
* `Pages` folder: Contains the Blazor app's routable Razor components (`.razor`). The route for each page is specified using the [`@page`](xref:mvc/views/razor#page) directive. The template includes the following components:
334338
* `Counter` component (`Counter.razor`): Implements the Counter page.
335339
* `Index` component (`Index.razor`): Implements the Home page.
336340
* `Weather` component (`Weather.razor`): Implements the Weather page.
337341

338-
moniker-end
342+
:::moniker-end
339343

340-
moniker range=">= aspnetcore-8.0"
344+
:::moniker range=">= aspnetcore-8.0"
341345

342346
* `_Imports.razor`: Includes common Razor directives to include in the app's components (`.razor`), such as [`@using`](xref:mvc/views/razor#using) directives for namespaces.
343347

aspnetcore/tutorials/web-api-help-pages-using-swagger.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
---
22
title: ASP.NET Core web API documentation with Swagger / OpenAPI
3+
ai-usage: ai-assisted
34
author: RicoSuter
45
description: This tutorial provides a walkthrough of adding Swagger to generate documentation and help pages for a web API app.
56
ms.author: wpickett
67
ms.custom: mvc
78
monikerRange: ">= aspnetcore-3.1 <= aspnetcore-8.0"
8-
ms.date: 4/25/2024
9+
ms.date: 02/23/2026
910
uid: tutorials/web-api-help-pages-using-swagger
1011
---
1112
# ASP.NET Core web API documentation with Swagger / OpenAPI
@@ -14,6 +15,15 @@ uid: tutorials/web-api-help-pages-using-swagger
1415

1516
By [Rico Suter](https://blog.rsuter.com/)
1617

18+
This article covers using **Swagger** tooling — provided by the [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) and [NSwag](https://github.com/RicoSuter/NSwag) packages — to generate OpenAPI documentation and interactive help pages for ASP.NET Core web APIs.
19+
20+
In .NET 9 and later, ASP.NET Core includes built-in OpenAPI support that replaces Swashbuckle as the default. Swashbuckle is no longer included in project templates, but it remains available as a community package you can add manually.
21+
22+
* To understand the built‑in OpenAPI features, see <xref:fundamentals/openapi/overview?view=aspnetcore-9.0&preserve-view=true>.
23+
* To add Swagger UI for interactive exploration or local ad‑hoc testing alongside the built-in OpenAPI support, see <xref:fundamentals/openapi/using-openapi-documents#use-swagger-ui-for-local-ad-hoc-testing>.
24+
25+
The following instructions apply to projects using Swashbuckle or NSwag with ASP.NET Core 8.0 and earlier.
26+
1727
[Swagger](https://swagger.io/) ([OpenAPI](https://www.openapis.org/)) is a language-agnostic specification for describing REST APIs. It allows both computers and humans to understand the capabilities of a REST API without direct access to the source code. Its main goals are to:
1828

1929
* Minimize the amount of work needed to connect decoupled services.
@@ -147,12 +157,14 @@ In the preceding code, the `/weatherforecast` endpoint doesn't need authorizatio
147157
The following Curl passes a JWT token to test the Swagger UI endpoint:
148158

149159
```bash
150-
curl -i -H "Authorization: Bearer {token}" https://localhost:{port}/swagger/v1/swagger.json
160+
curl -i -H "Authorization: Bearer {TOKEN}" https://localhost:{PORT}/swagger/v1/swagger.json
151161
```
152162

163+
where the `{TOKEN}` placeholder is the JWT bearer token and the `{PORT}` placeholder is the port number.
164+
153165
For more information on testing with JWT tokens, see <xref:security/authentication/jwt>.
154166

155-
## Generate an XML documentation file at compile time.
167+
## Generate an XML documentation file at compile time
156168

157169
See [GenerateDocumentationFile](/dotnet/core/project-sdk/msbuild-props#generatedocumentationfile) for more information.
158170

0 commit comments

Comments
 (0)