Skip to content
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

Merge to Live #34544

Open
wants to merge 6 commits into
base: live
Choose a base branch
from
Open
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
4 changes: 2 additions & 2 deletions aspnetcore/blazor/components/event-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ For event handling:
:::moniker range=">= aspnetcore-8.0"

* Delegate event handlers in Blazor Web Apps are only called in components that adopt an interactive render mode. The examples throughout this article assume that the app adopts an interactive render mode globally in the app's root component, typically the `App` component. For more information, see <xref:blazor/components/render-modes#apply-a-render-mode-to-the-entire-app>.
* Asynchronous delegate event handlers that return a <xref:System.Threading.Tasks.Task> are supported.
* Asynchronous delegate event handlers that return a <xref:System.Threading.Tasks.Task> (`async Task`) are supported by Blazor and adopted by Blazor Web App and Blazor WebAssembly documentation examples.
* Delegate event handlers automatically trigger a UI render, so there's no need to manually call [`StateHasChanged`](xref:blazor/components/lifecycle#state-changes-statehaschanged).
* Exceptions are logged.

:::moniker-end

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

* Asynchronous delegate event handlers that return a <xref:System.Threading.Tasks.Task> are supported.
* Asynchronous delegate event handlers that return a <xref:System.Threading.Tasks.Task> (`async Task`) are supported by Blazor and adopted by Blazor Server and Blazor WebAssembly documentation examples.
* Delegate event handlers automatically trigger a UI render, so there's no need to manually call [`StateHasChanged`](xref:blazor/components/lifecycle#state-changes-statehaschanged).
* Exceptions are logged.

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/includes/js-interop/js-collocation.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ The following `JsCollocation2` component's `OnAfterRenderAsync` method loads a J
}
}

public async void ShowPrompt()
public async Task ShowPrompt()
{
if (module is not null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ There's no limit on the number of connections per user for an app. If the app re
* Require authentication to connect to the app and keep track of the active sessions per user.
* Reject new sessions upon reaching a limit.
* Proxy WebSocket connections to an app through the use of a proxy, such as the [Azure SignalR Service](/azure/azure-signalr/signalr-overview) that multiplexes connections from clients to an app. This provides an app with greater connection capacity than a single client can establish, preventing a client from exhausting the connections to the server.
* Server level
* Use a proxy/gateway in front of the app. For example, [Azure Application Gateway](/azure/application-gateway/overview) is a web traffic (OSI layer 7) load balancer that enables you to manage traffic to your web applications. For more information, see [Overview of WebSocket support in Application Gateway](/azure/application-gateway/application-gateway-websocket).
* Although Long Polling is supported for Blazor apps, which would permit the adoption of [Azure Front Door](/azure/frontdoor/front-door-overview), [WebSockets is the recommended transport protocol](xref:blazor/host-and-deploy/server#azure-signalr-service). As of September, 2024, [Azure Front Door](/azure/frontdoor/front-door-overview) doesn't support WebSockets, but support for WebSockets is under consideration. For more information, see [Support WebSocket connections on Azure Front Door](https://feedback.azure.com/d365community/idea/c8b1d257-8a26-ec11-b6e6-000d3a4f0789).
* Server level: Use a proxy/gateway in front of the app.
* [Azure Application Gateway](/azure/application-gateway/overview) is a web traffic (OSI layer 7) load balancer that enables you to manage traffic to your web applications. For more information, see [Overview of WebSocket support in Application Gateway](/azure/application-gateway/application-gateway-websocket).
* [Azure Front Door](/azure/frontdoor/front-door-overview) is a load-balancing service for distributing your workloads across multiple computing resources.

:::moniker-end

Expand Down
143 changes: 71 additions & 72 deletions aspnetcore/blazor/webassembly-native-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,64 +36,62 @@ Prebuilt dependencies typically must be built using the same version of Emscript

## Use native code

Add a simple native C function to a Blazor WebAssembly app:
This section demonstrates how to add a simple native C function to a Blazor WebAssembly app.

1. Create a new Blazor WebAssembly project.
1. Add a `Test.c` file to the project.
1. Add a C function for computing factorials.
Create a new Blazor WebAssembly project.

`Test.c`:
Add a `Test.c` file to the project with a C function for computing factorials.

```c
int fact(int n)
{
if (n == 0) return 1;
return n * fact(n - 1);
}
```
`Test.c`:

1. Add a `NativeFileReference` for `Test.c` in the app's project file:
```c
int fact(int n)
{
if (n == 0) return 1;
return n * fact(n - 1);
}
```

```xml
<ItemGroup>
<NativeFileReference Include="Test.c" />
</ItemGroup>
```
Add a `NativeFileReference` MS Build item for `Test.c` in the app's project file (`.csproj`):

1. In a Razor component, add a <xref:System.Runtime.InteropServices.DllImportAttribute> for the `fact` function in the generated `Test` library and call the `fact` method from .NET code in the component.
```xml
<ItemGroup>
<NativeFileReference Include="Test.c" />
</ItemGroup>
```

`Pages/NativeCTest.razor`:
In a Razor component, add a [`[DllImport]` attribute](xref:System.Runtime.InteropServices.DllImportAttribute) for the `fact` function in the generated `Test` library and call the `fact` method from .NET code in the component.

```razor
@page "/native-c-test"
@using System.Runtime.InteropServices
`Pages/NativeCTest.razor`:

<PageTitle>Native C</PageTitle>
```razor
@page "/native-c-test"
@using System.Runtime.InteropServices

<h1>Native C Test</h1>
<PageTitle>Native C</PageTitle>

<p>
@@fact(3) result: @fact(3)
</p>
<h1>Native C Test</h1>

@code {
[DllImport("Test")]
static extern int fact(int n);
}
```
<p>
@@fact(3) result: @fact(3)
</p>

@code {
[DllImport("Test")]
static extern int fact(int n);
}
```

When you build the app with the .NET WebAssembly build tools installed, the native C code is compiled and linked into the .NET WebAssembly runtime (`dotnet.wasm`). After the app is built, run the app to see the rendered factorial value.

## C++ managed method callbacks

Label managed methods that are passed to C++ with the `[UnmanagedCallersOnly]` attribute.

The method marked with the `[UnmanagedCallersOnly]` attribute must be `static`. To call an instance method in a Razor component, pass a `GCHandle` for the instance to C++ and then pass it back to native. Alternatively, use some other method to identify the instance of the component.
Label managed methods that are passed to C++ with the [`[UnmanagedCallersOnly]` attribute](xref:System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute). The method marked with the attribute must be `static`. To call an instance method in a Razor component, pass a <xref:System.Runtime.InteropServices.GCHandle> for the instance to C++ and then pass it back to native. Alternatively, use some other method to identify the instance of the component.

The method marked with `[DllImport]` must use a C# 9.0 function pointer rather than a delegate type for the callback argument.
The method marked with the [`[DllImport]` attribute](xref:System.Runtime.InteropServices.DllImportAttribute) must use a [function pointer (C# 9.0 or later)](/dotnet/csharp/language-reference/proposals/csharp-9.0/function-pointers) rather than a delegate type for the callback argument.

> [!NOTE]
> For C# function pointer types in `[DllImport]` methods, use `IntPtr` in the method signature on the managed side instead of `delegate *unmanaged<int, void>`. For more information, see [[WASM] callback from native code to .NET: Parsing function pointer types in signatures is not supported (dotnet/runtime #56145)](https://github.com/dotnet/runtime/issues/56145).
> For C# function pointer types in [`[DllImport]`](xref:System.Runtime.InteropServices.DllImportAttribute) methods, use <xref:System.IntPtr> in the method signature on the managed side instead of `delegate *unmanaged<int, void>`. For more information, see [[WASM] callback from native code to .NET: Parsing function pointer types in signatures is not supported (`dotnet/runtime` #56145)](https://github.com/dotnet/runtime/issues/56145).

## Package native dependencies in a NuGet package

Expand All @@ -103,55 +101,56 @@ NuGet packages can contain native dependencies for use on WebAssembly. These lib

[SkiaSharp](https://github.com/mono/SkiaSharp) is a cross-platform 2D graphics library for .NET based on the native [Skia graphics library](https://skia.org/) with support for Blazor WebAssembly.

To use SkiaSharp in a Blazor WebAssembly app:
The section demonstrates how to implement SkiaSharp in a Blazor WebAssembly app.

1. Add a package reference to the [`SkiaSharp.Views.Blazor`](https://www.nuget.org/packages/SkiaSharp.Views.Blazor) package in a Blazor WebAssembly project. Use Visual Studio's process for adding packages to an app (**Manage NuGet Packages** with **Include prerelease** selected) or execute the [`dotnet add package`](/dotnet/core/tools/dotnet-add-package) command in a command shell:
Add a package reference to the [`SkiaSharp.Views.Blazor`](https://www.nuget.org/packages/SkiaSharp.Views.Blazor) package in a Blazor WebAssembly project. Use Visual Studio's process for adding packages to an app (**Manage NuGet Packages** with **Include prerelease** selected) or execute the [`dotnet add package`](/dotnet/core/tools/dotnet-add-package) command in a command shell with the `--prerelease` option:

```dotnetcli
dotnet add package –-prerelease SkiaSharp.Views.Blazor
```
```dotnetcli
dotnet add package –-prerelease SkiaSharp.Views.Blazor
```

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

1. Add a `SKCanvasView` component to the app with the following:
Add a `SKCanvasView` component to the app with the following:

* `SkiaSharp` and `SkiaSharp.Views.Blazor` namespaces.
* Logic to draw in the SkiaSharp Canvas View component (`SKCanvasView`).
* `SkiaSharp` and `SkiaSharp.Views.Blazor` namespaces.
* Logic to draw in the SkiaSharp Canvas View component (`SKCanvasView`).

`Pages/NativeDependencyExample.razor`:
`Pages/NativeDependencyExample.razor`:

```razor
@page "/native-dependency-example"
@using SkiaSharp
@using SkiaSharp.Views.Blazor
```razor
@page "/native-dependency-example"
@using SkiaSharp
@using SkiaSharp.Views.Blazor

<PageTitle>Native dependency</PageTitle>
<PageTitle>Native dependency</PageTitle>

<h1>Native dependency example with SkiaSharp</h1>
<h1>Native dependency example with SkiaSharp</h1>

<SKCanvasView OnPaintSurface="OnPaintSurface" />
<SKCanvasView OnPaintSurface="OnPaintSurface" />

@code {
private void OnPaintSurface(SKPaintSurfaceEventArgs e)
{
var canvas = e.Surface.Canvas;
@code {
private void OnPaintSurface(SKPaintSurfaceEventArgs e)
{
var canvas = e.Surface.Canvas;

canvas.Clear(SKColors.White);
canvas.Clear(SKColors.White);

using var paint = new SKPaint
{
Color = SKColors.Black,
IsAntialias = true,
TextSize = 24
};
using var paint = new SKPaint
{
Color = SKColors.Black,
IsAntialias = true,
TextSize = 24
};

canvas.DrawText("SkiaSharp", 0, 24, paint);
}
}
```
canvas.DrawText("SkiaSharp", 0, 24, paint);
}
}
```

1. Build the app, which might take several minutes. Run the app and navigate to the `NativeDependencyExample` component at `/native-dependency-example`.
Build the app, which might take several minutes. Run the app and navigate to the `NativeDependencyExample` component at `/native-dependency-example`.

## Additional resources

[.NET WebAssembly build tools](xref:blazor/tooling/webassembly)
* [.NET WebAssembly build tools](xref:blazor/tooling/webassembly)
* [Mono/WebAssembly MSBuild properties and targets (`WasmApp.targets`, `dotnet/runtime` GitHub repository)](https://github.com/dotnet/runtime/blob/main/src/mono/wasm/build/WasmApp.Common.targets)
4 changes: 2 additions & 2 deletions aspnetcore/security/authorization/roles.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ Access to an action can be limited by applying additional role authorization att

In the preceding `ControlAllPanelController` controller:

* Members of the `Administrator` role or the `PowerUser` role can access the controller and the `ShutDown` action.
* Only members of the `Administrator` role can access the `SetTime` action.
* Members of the `Administrator` role or the `PowerUser` role can access the controller and the `SetTime` action.
* Only members of the `Administrator` role can access the `ShutDown` action.

A controller can be secured but allow anonymous, unauthenticated access to individual actions:

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/web-api/advanced/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Conventions don't compose; each action may be associated with exactly one conven
[ProducesResponseType(StatusCodes.Status400BadRequest)]
```

For more information on `[ProducesDefaultResponseType]`, see [Default Response](https://swagger.io/docs/specification/describing-responses/#default).
For more information on `[ProducesDefaultResponseType]`, see [Default Response](https://swagger.io/docs/specification/describing-responses/#default-response).

1. `Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute` applied to a controller &mdash; Applies the specified convention type to all actions on the controller. A convention method is marked with hints that determine the actions to which the convention method applies. For more information on hints, see [Create web API conventions](#create-web-api-conventions)).

Expand Down
Loading