Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions aspnetcore/blazor/components/data-binding.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,14 +221,14 @@ Additional examples

For more information on the `InputText` component, see <xref:blazor/forms/input-components>.

Components support two-way data binding by defining a pair of parameters:
Components support two-way data binding by defining a pair of `@bind` attributes with either a `:get` or `:set` modifier . The `{PARAMETER}` placeholder in the following examples is used to bind a component parameter:

* `@bind:get`: Specifies the value to bind.
* `@bind:set`: Specifies a callback for when the value changes.
* `@bind:get`/`@bind-{PARAMETER}:get`: Specifies the value to bind.
* `@bind:set`/`@bind-{PARAMETER}:set`: Specifies a callback for when the value changes.

The `@bind:get` and `@bind:set` modifiers are always used together.
The `:get` and `:set` modifiers are always used together.

Examples
With `:get`/`:set` binding, you can react to a value change before it's applied to the DOM, and you can change the applied value, if necessary. Whereas with `@bind:event="{EVENT}"` attribute binding, where the `{EVENT}` placeholder is a DOM event, you receive the notification after the DOM is updated, and there's no capacity to modify the applied value while binding.

`BindGetSet.razor`:

Expand Down Expand Up @@ -378,14 +378,16 @@ Using `@bind:get`/`@bind:set` modifiers both controls the underlying value of `i
:::moniker range=">= aspnetcore-7.0"

> [!NOTE]
> Two-way binding to a property with `get`/`set` accessors requires discarding the <xref:System.Threading.Tasks.Task> returned by <xref:Microsoft.AspNetCore.Components.EventCallback.InvokeAsync%2A?displayProperty=nameWithType>. For two-way data binding, we recommend using `@bind:get`/`@bind:set` modifiers. For more information, see the `@bind:get`/`@bind:set` guidance in the earlier in this article.
> Across multiple components, two-way binding to a property with `get`/`set` accessors requires discarding the <xref:System.Threading.Tasks.Task> returned by <xref:Microsoft.AspNetCore.Components.EventCallback.InvokeAsync%2A?displayProperty=nameWithType> in the property's setter. For two-way data binding, we recommend using `@bind:get`/`@bind:set` modifiers. For more information, see the [`@bind:get`/`@bind:set` guidance](#binding-features) earlier in this article.
>
> To see an example of how the <xref:System.Threading.Tasks.Task> returned by <xref:Microsoft.AspNetCore.Components.EventCallback.InvokeAsync%2A?displayProperty=nameWithType> is discarded in .NET 6 or earlier before `@bind:get`/`@bind:set` modifiers became a framework feature, see [the `NestedChild` component of the *Bind across more than two components* section in the .NET 6 version of this article](?view=aspnetcore-6.0&preserve-view=true#bind-across-more-than-two-components).

:::moniker-end

:::moniker range="< aspnetcore-7.0"

> [!NOTE]
> Two-way binding to a property with `get`/`set` accessors requires discarding the <xref:System.Threading.Tasks.Task> returned by <xref:Microsoft.AspNetCore.Components.EventCallback.InvokeAsync%2A?displayProperty=nameWithType>. For two-way data binding in ASP.NET Core in .NET 7 or later, we recommend using `@bind:get`/`@bind:set` modifiers, which are described in 7.0 or later versions of this article.
> Two-way binding to a property with `get`/`set` accessors requires discarding the <xref:System.Threading.Tasks.Task> returned by <xref:Microsoft.AspNetCore.Components.EventCallback.InvokeAsync%2A?displayProperty=nameWithType>. For an example, see [the `NestedChild` component of the *Bind across more than two components* section](#bind-across-more-than-two-components). For two-way data binding in .NET 7 or later, we recommend using `@bind:get`/`@bind:set` modifiers, which are described in 7.0 or later versions of this article.

:::moniker-end

Expand Down Expand Up @@ -889,6 +891,8 @@ In the following `NestedChild` component, the `NestedGrandchild` component:
* Assigns the value of `ChildMessage` to `GrandchildMessage` with `@bind:get` syntax.
* Updates `GrandchildMessage` when `ChildMessageChanged` executes with `@bind:set` syntax.

Prior to the release of .NET 7, two-way binding across components uses `get`/`set` accessors with a third property that discards the <xref:System.Threading.Tasks.Task> returned by <xref:Microsoft.AspNetCore.Components.EventCallback.InvokeAsync%2A?displayProperty=nameWithType> in its setter. To see an example of this approach for .NET 6 or earlier before `@bind:get`/`@bind:set` modifiers became a framework feature, see [the `NestedChild` component of this section in the .NET 6 version of this article](?view=aspnetcore-6.0&preserve-view=true#bind-across-more-than-two-components).

:::moniker-end

`NestedChild.razor`:
Expand Down
13 changes: 13 additions & 0 deletions aspnetcore/blazor/globalization-localization.md
Original file line number Diff line number Diff line change
Expand Up @@ -1670,12 +1670,25 @@ To further understand how the Blazor framework processes localization, see the [

To create localization shared resources, adopt the following approach.

* Confirm that the [`Microsoft.Extensions.Localization`](https://www.nuget.org/packages/Microsoft.Extensions.Localization) package is referenced by the project.

[!INCLUDE[](~/includes/package-reference.md)]

* Confirm that the <xref:Microsoft.Extensions.Localization?displayProperty=fullName> namespace is available to the project's Razor components via an entry in the project's `_Imports` file:

```razor
@using Microsoft.Extensions.Localization
```

* Create a dummy class with an arbitrary class name. In the following example:

* The app uses the `BlazorSample` namespace, and localization assets use the `BlazorSample.Localization` namespace.
* The dummy class is named `SharedResource`.
* The class file is placed in a `Localization` folder at the root of the app.

> [!NOTE]
> Don't use an autogenerated designer file (for example, `SharedResources.Designer.cs`). The dummy class is meant to act as the shared resource class. The presence of a designer file results in a namespace collision.

`Localization/SharedResource.cs`:

```csharp
Expand Down
10 changes: 4 additions & 6 deletions aspnetcore/blazor/host-and-deploy/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,20 @@ Publish locations:

:::moniker range=">= aspnetcore-8.0"

* Blazor Web App: The app is published into the `/bin/Release/{TARGET FRAMEWORK}/publish` folder. Deploy the contents of the `publish` folder to the host.
* Blazor WebAssembly: The app is published into the `bin\Release\net8.0\browser-wasm\publish\` folder. To deploy the app as a static site, copy the contents of the `wwwroot` folder to the static site host.
* Blazor Web App: The app is published into the `/bin/Release/{TARGET FRAMEWORK}/publish` folder, where the `{TARGET FRAMEWORK}` placeholder is the target framework. Deploy the contents of the `publish` folder to the host.
* Standalone Blazor WebAssembly: The app is published into the `bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish\` folder. To deploy the app as a static site, copy the contents of the `wwwroot` folder to the static site host.

:::moniker-end

:::moniker range="< aspnetcore-8.0"

* Blazor Server: The app is published into the `/bin/Release/{TARGET FRAMEWORK}/publish` folder. Deploy the contents of the `publish` folder to the host.
* Blazor Server: The app is published into the `/bin/Release/{TARGET FRAMEWORK}/publish` folder, where the `{TARGET FRAMEWORK}` placeholder is the target framework.. Deploy the contents of the `publish` folder to the host.
* Blazor WebAssembly
* Standalone: The app is published into the `/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot` or `bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish` folder, depending on the version of the SDK used to publish the app. To deploy the app as a static site, copy the contents of the `wwwroot` folder to the static site host.
* Hosted: The client Blazor WebAssembly app is published into the `/bin/Release/{TARGET FRAMEWORK}/publish/wwwroot` folder of the server app, along with any other static web assets of the client app. Deploy the contents of the `publish` folder to the host.

:::moniker-end

The `{TARGET FRAMEWORK}` in the preceding paths is the target framework (for example, `net8.0`).

## IIS

To host a Blazor app in IIS, see the following resources:
Expand Down Expand Up @@ -115,7 +113,7 @@ An anchor tag's destination ([`href`](https://developer.mozilla.org/docs/Web/HTM

The presence of a trailing slash (`/`) in a configured app base path is significant to compute the base path for URLs of the app. For example, `https://example.com/a` has a base path of `https://example.com/`, while `https://example.com/a/` with a trailing slash has a base path of `https://example.com/a`.

There are three sources of links that pertain to Blazor in ASP.NET Core apps:
For the sources of links that pertain to Blazor in ASP.NET Core apps:

:::moniker range=">= aspnetcore-8.0"

Expand Down
4 changes: 1 addition & 3 deletions aspnetcore/blazor/hybrid/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,9 @@ When dynamically changing the app culture at runtime, the app must be reloaded t

.NET's resource system supports embedding localized images (as blobs) into an app, but Blazor Hybrid can't display the embedded images in Razor components at this time. Even if a user reads an image's bytes into a <xref:System.IO.Stream> using <xref:System.Resources.ResourceManager>, the framework doesn't currently support rendering the retrieved image in a Razor component.

[A platform-specific approach to include localized images](/xamarin/xamarin-forms/user-interface/images#local-images) is a feature of .NET's resource system, but a Razor component's browser elements in a .NET MAUI Blazor Hybrid app aren't able to interact with such images.

For more information, see the following resources:

* [Xamarin.Forms String and Image Localization](/xamarin/xamarin-forms/app-fundamentals/localization/): The guidance generally applies to Blazor Hybrid apps. Not every scenario is supported at this time.
* [Localization (.NET MAUI documentation)](/dotnet/maui/fundamentals/localization)
* [Blazor Image component to display images that are not accessible through HTTP endpoints (dotnet/aspnetcore #25274)](https://github.com/dotnet/aspnetcore/issues/25274)

:::moniker range=">= aspnetcore-8.0"
Expand Down
4 changes: 2 additions & 2 deletions aspnetcore/blazor/hybrid/security/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ After authentication is added to a .NET MAUI, WPF, or Windows Forms app and user

:::zone pivot="maui"

.NET MAUI apps use [Xamarin.Essentials: Web Authenticator](/xamarin/essentials/web-authenticator): The `WebAuthenticator` class allows the app to initiate browser-based authentication flows that listen for a callback to a specific URL registered with the app.
.NET MAUI apps use the `WebAuthenticator` class to initiate browser-based authentication flows that listen for a callback to a specific URL registered with the app.

For additional guidance, see the following resources:

Expand Down Expand Up @@ -574,7 +574,7 @@ After authentication is added to a .NET MAUI, WPF, or Windows Forms app and user

:::zone pivot="maui"

.NET MAUI apps use [Xamarin.Essentials: Web Authenticator](/xamarin/essentials/web-authenticator): The `WebAuthenticator` class allows the app to initiate browser-based authentication flows that listen for a callback to a specific URL registered with the app.
.NET MAUI apps use the `WebAuthenticator` class to initiate browser-based authentication flows that listen for a callback to a specific URL registered with the app.

For additional guidance, see the following resources:

Expand Down
4 changes: 2 additions & 2 deletions aspnetcore/blazor/hybrid/tutorials/maui.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ In the **Create a Default Android Device** window, select the **Create** button:
Wait for Visual Studio to download, unzip, and create an Android Emulator. When the Android phone emulator is ready, select the **Start** button.

> [!NOTE]
> [Enable hardware acceleration](/xamarin/android/get-started/installation/android-emulator/hardware-acceleration) to improve the performance of the Android emulator.
> [Enable hardware acceleration](/dotnet/maui/android/emulator/hardware-acceleration) to improve the performance of the Android emulator.

Close the **Android Device Manager** window. Wait until the emulated phone window appears, the Android OS loads, and the home screen appears.

Expand All @@ -132,7 +132,7 @@ In the Visual Studio toolbar, select the **:::no-loc text="Pixel 5 - {VERSION}":

Visual Studio builds the project and deploys the app to the emulator.

Starting the emulator, loading the emulated phone and OS, and deploying and running the app can take several minutes depending on the speed of the system and whether or not [hardware acceleration](/xamarin/android/get-started/installation/android-emulator/hardware-acceleration) is enabled. You can monitor the progress of the deployment by inspecting Visual Studio's status bar at the bottom of the UI. The **Ready** indicator receives a checkmark and the emulator's deployment and app loading indicators disappear when the app is running:
Starting the emulator, loading the emulated phone and OS, and deploying and running the app can take several minutes depending on the speed of the system and whether or not [hardware acceleration](/dotnet/maui/android/emulator/hardware-acceleration) is enabled. You can monitor the progress of the deployment by inspecting Visual Studio's status bar at the bottom of the UI. The **Ready** indicator receives a checkmark and the emulator's deployment and app loading indicators disappear when the app is running:

During deployment:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ When working with <xref:Microsoft.JSInterop.IJSObjectReference> in ASP.NET Core

```razor
@inject IJSRuntime JS
@implements IAsyncDisposable
@implements IDisposable

...

Expand All @@ -36,18 +36,20 @@ When working with <xref:Microsoft.JSInterop.IJSObjectReference> in ASP.NET Core
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSInProcessObjectReference>("import",
"./scripts.js");
var jsInProcess = (IJSInProcessRuntime)JS;
module = await jsInProcess.Invoke<IJSInProcessObjectReference>("import",
"./scripts.js");
var value = module.Invoke<string>("javascriptFunctionIdentifier");
}
}

...

async ValueTask IAsyncDisposable.DisposeAsync()
void IDisposable.Dispose()
{
if (module is not null)
{
await module.DisposeAsync();
await module.Dispose();
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ For apps that require third-party JavaScript libraries and access to browser API

## Code sharing and .NET Standard

Blazor implements the [.NET Standard](/dotnet/standard/net-standard), which enables Blazor projects to reference libraries that conform to .NET Standard specifications. .NET Standard is a formal specification of .NET APIs that are common across .NET implementations. .NET Standard class libraries can be shared across different .NET platforms, such as Blazor, .NET Framework, .NET Core, Xamarin, Mono, and Unity.
Blazor implements the [.NET Standard](/dotnet/standard/net-standard), which enables Blazor projects to reference libraries that conform to .NET Standard specifications. .NET Standard is a formal specification of .NET APIs that are common across .NET implementations. .NET Standard class libraries can be shared across different .NET platforms, such as Blazor, .NET Framework, .NET Core, .NET Multi-platform App UI (.NET MAUI), Mono, and Unity.

APIs that aren't applicable inside of a web browser (for example, accessing the file system, opening a socket, and threading) throw a <xref:System.PlatformNotSupportedException>.

Expand Down
16 changes: 16 additions & 0 deletions aspnetcore/blazor/security/blazor-web-app-with-oidc.md
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,22 @@ The important changes to the `LogInOrOut` component are demonstrated in the foll
</div>
```

:::moniker range="< aspnetcore-10.0"

## Token refresh

<!-- UPDATE 10.0 - Check the PU issue for 10.0 work to resolve both issues.
The docs issue is https://github.com/dotnet/AspNetCore.Docs/issues/34235. -->

The custom cookie refresher (`CookieOidcRefresher.cs`) implementation updates the user's claims automatically when they expire. The current implementation expects to receive an ID token from the token endpoint in exchange for the refresh token. The claims in this ID token are then used to overwrite the user's claims.

The sample implementation doesn't include code for requesting claims from the [UserInfo endpoint](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo) on token refresh. For more information, see [`BlazorWebAppOidc AddOpenIdConnect with GetClaimsFromUserInfoEndpoint = true doesn't propogate role claims to client` (`dotnet/aspnetcore` #58826)](https://github.com/dotnet/aspnetcore/issues/58826#issuecomment-2492738142).

> [!NOTE]
> Some identity providers [only return an access token when using a refresh token](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokenResponse). The `CookieOidcRefresher` can be updated with additional logic to continue to use the prior set of claims stored in the authentication cookie or use the access token to request claims from the UserInfo endpoint.

:::moniker-end

## Cryptographic nonce

A *nonce* is a string value that associates a client's session with an ID token to mitigate [replay attacks](https://developer.mozilla.org/docs/Glossary/Replay_attack).
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions aspnetcore/fundamentals/openapi/using-openapi-documents.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ The `Swashbuckle.AspNetCore.SwaggerUi` package provides a bundle of Swagger UI's

[!code-csharp[](~/fundamentals/openapi/samples/9.x/WebMinOpenApi/Program.cs?name=snippet_openapiwithscalar)]

Launch the app and navigate to `https://localhost:<port>/scalar/v1` to view the Scalar UI.

## Lint generated OpenAPI documents with Spectral

[Spectral](https://stoplight.io/open-source/spectral) is an open-source OpenAPI document linter. Spectral can be incorporated into an app build to verify the quality of generated OpenAPI documents. Install Spectral according to the [package installation directions](https://github.com/stoplightio/spectral#-installation).
Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/tutorials/first-mvc-app/details.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ uid: tutorials/first-mvc-app/details

[!INCLUDE[](~/includes/not-latest-version.md)]

By [Rick Anderson](https://twitter.com/RickAndMSFT)
By [Rick Anderson](https://twitter.com/RickAndMSFT) and Bryan Kaplan 2023 JHF trail

:::moniker range=">= aspnetcore-9.0"

Expand Down
Loading