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
4 changes: 3 additions & 1 deletion aspnetcore/blazor/fundamentals/static-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Assets are delivered via the <xref:Microsoft.AspNetCore.Components.ComponentBase

## `ImportMap` component

*This section applies to server-side Blazor apps.*
*This section applies to Blazor Web Apps that call <xref:Microsoft.AspNetCore.Builder.RazorComponentsEndpointRouteBuilderExtensions.MapRazorComponents%2A>.*

The `ImportMap` component (<xref:Microsoft.AspNetCore.Components.ImportMap>) represents an import map element (`<script type="importmap"></script>`) that defines the import map for module scripts. The Import Map component is placed in `<head>` content of the root component, typically the `App` component (`Components/App.razor`).

Expand Down Expand Up @@ -190,6 +190,8 @@ The preceding code results in the following import map:

## Import map Content Security Policy (CSP) violations

*This section applies to Blazor Web Apps that call <xref:Microsoft.AspNetCore.Builder.RazorComponentsEndpointRouteBuilderExtensions.MapRazorComponents%2A>.*

The `ImportMap` component is rendered as an inline `<script>` tag, which violates a strict [Content Security Policy (CSP)](https://developer.mozilla.org/docs/Web/HTTP/Guides/CSP) that sets the `default-src` or `script-src` directive.

For examples of how to address the policy violation with Subresource Integrity (SRI) or a cryptographic nonce, see [Resolving CSP violations with Subresource Integrity (SRI) or a nonce](xref:blazor/security/content-security-policy#resolving-csp-violations-with-subresource-integrity-sri-or-a-cryptographic-nonce).
Expand Down
8 changes: 4 additions & 4 deletions aspnetcore/blazor/hosting-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,18 @@ The Blazor WebAssembly hosting model runs components client-side in the browser

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

Blazor web apps can use the Blazor WebAssembly hosting model to enable client-side interactivity. When an app is created that exclusively runs on the Blazor WebAssembly hosting model without server-side rendering and interactivity, the app is called a *standalone* Blazor WebAssembly app.
Blazor Web Apps can use the Blazor WebAssembly hosting model to enable client-side interactivity. When an app is created that exclusively runs on the Blazor WebAssembly hosting model without server-side rendering and interactivity, the app is called a *standalone* Blazor WebAssembly app.

:::moniker-end

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

When the Blazor WebAssembly app is created for deployment without a backend ASP.NET Core app to serve its files, the app is called a *standalone* Blazor WebAssembly app.

:::moniker-end

When a standalone Blazor WebAssembly app uses a backend ASP.NET Core app to serve its files, the app is called a *hosted* Blazor WebAssembly app. Using hosted Blazor WebAssembly, you get a full-stack web development experience with .NET, including the ability to share code between the client and server apps, support for prerendering, and integration with MVC and Razor Pages. A hosted client app can interact with its backend server app over the network using a variety of messaging frameworks and protocols, such as [web API](xref:web-api/index), [gRPC-web](xref:grpc/index), and [SignalR](xref:signalr/introduction) (<xref:blazor/tutorials/signalr-blazor>).

:::moniker-end

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

A Blazor WebAssembly app built as a [Progressive Web App (PWA)](xref:blazor/progressive-web-app) uses modern browser APIs to enable many of the capabilities of a native client app, such as working offline, running in its own app window, launching from the host's operating system, receiving push notifications, and automatically updating in the background.
Expand Down Expand Up @@ -420,7 +420,7 @@ Blazor Hybrid apps have full access to native client API capabilities via .NET n

### Web-based deployment

Blazor web apps are updated on the next app refresh from the browser.
Blazor Web Apps are updated on the next app refresh from the browser.

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ iOS and :::no-loc text="Mac Catalyst"::: both use [`WKWebView`](https://develope

### Windows (.NET MAUI, WPF, Windows Forms)

On Windows, the Chromium-based [Microsoft Edge `WebView2`](/microsoft-edge/webview2/) is required to run Blazor web apps.
On Windows, the Chromium-based [Microsoft Edge `WebView2`](/microsoft-edge/webview2/) is required to run Blazor Web Apps.

The newest installed version of `WebView2`, known as the *:::no-loc text="Evergreen distribution":::*, is used. If you wish to ship a specific version of `WebView2` with the app, use the *:::no-loc text="Fixed Version distribution":::*.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,107 @@ IJSRuntime JS { get; set; }

[!INCLUDE[](~/blazor/includes/js-interop/synchronous-js-interop-call-js.md)]

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

<!-- UPDATE 10.0 - API Browser cross-links in the next
two H2 sections. -->

## Create an instance of a JS object using a constructor function

Create an instance of a JS object using a constructor function and get the <xref:Microsoft.JSInterop.IJSObjectReference>/<xref:Microsoft.JSInterop.IJSInProcessObjectReference> .NET handle for referencing the instance with the following API:

* `InvokeNewAsync` (asynchronous)
* `InvokeNew` (synchronous)

Examples in this section demonstrate the API calls with the following `TestClass` with a constructor function (`constructor(text)`):

```javascript
window.TestClass = class {
constructor(text) {
this.text = text;
}

getTextLength() {
return this.text.length;
}
}
```

### Asynchronous `InvokeNewAsync`

Use `InvokeNewAsync(string identifier, object?[]? args)` on <xref:Microsoft.JSInterop.IJSRuntime> and <xref:Microsoft.JSInterop.IJSObjectReference> to invoke the specified JS constructor function asynchronously. The function is invoked with the `new` operator. In the following example, `TestClass` contains a constructor function, and `classRef` is an <xref:Microsoft.JSInterop.IJSObjectReference>.

```csharp
var classRef = await JSRuntime.InvokeNewAsync("TestClass", "Blazor!");
var text = await classRef.GetValueAsync<string>("text");
var textLength = await classRef.InvokeAsync<int>("getTextLength");
```

An overload is available that takes a <xref:System.Threading.CancellationToken> argument or <xref:System.TimeSpan> timeout argument.

### Synchronous `InvokeNew`

Use `InvokeNew(string identifier, object?[]? args)` on <xref:Microsoft.JSInterop.IJSInProcessRuntime> and <xref:Microsoft.JSInterop.IJSInProcessObjectReference> to invoke the specified JS constructor function synchronously. The function is invoked with the `new` operator. In the following example, `TestClass` contains a constructor function, and `classRef` is an <xref:Microsoft.JSInterop.IJSInProcessObjectReference>:

```csharp
var inProcRuntime = ((IJSInProcessRuntime)JSRuntime);
var classRef = inProcRuntime.InvokeNew("TestClass", "Blazor!");
var text = await classRef.GetValueAsync<string>("text");
var textLength = await classRef.InvokeAsync<int>("getTextLength");
```

An overload is available that takes a <xref:System.Threading.CancellationToken> argument or <xref:System.TimeSpan> timeout argument.

## Read or modify the value of a JS object property

Read or modify the value of a JS object property, both data and accessor properties, with the following API:

* `GetValueAsync`/`SetValueAsync` (asynchronous)
* `GetValue`/`SetValue` (synchronous)

Examples in this section demonstrate the API calls with the following JS object (`testObject`):

```javascript
window.testObject = {
num: 10
}
```

### Asynchronous `GetValueAsync` and `SetValueAsync`

Use `GetValueAsync<TValue>(string identifier)` to read the value of the specified JS property asynchronously. A <xref:Microsoft.JSInterop.JSException> is thrown if the property doesn't exist or is a `set`-only property. In the following example, the value of `testObject.num` (10) is stored in `valueFromDataPropertyAsync`:

```csharp
var valueFromDataPropertyAsync =
await JSRuntime.GetValueAsync<int>("testObject.num");
```

Use `SetValueAsync<TValue>(string identifier, TValue value)` to update the value of the specified JS property asynchronously. If the property isn't defined on the target object, the property is created. A <xref:Microsoft.JSInterop.JSException> is thrown if the property exists but isn't writable or when a new property can't be added to the object. In the following example, `testObject.num` is set to 20, and `num2` is created with a value of 30 on `testObject`:

```csharp
await JSRuntime.SetValueAsync("testObject.num", 20);
await JSRuntime.SetValueAsync("testObject.num2", 30);
```

### Synchronous `GetValue` and `SetValue`

Use `GetValue<TValue>(string identifier)` to read the value of the specified JS property synchronously. A <xref:Microsoft.JSInterop.JSException> is thrown if the property doesn't exist or is a `set`-only property. In the following example, the value of `testObject.num` (10) is stored in `valueFromDataProperty`:

```csharp
var inProcRuntime = ((IJSInProcessRuntime)JSRuntime);
var valueFromDataProperty = inProcRuntime.GetValue<int>("testObject.num");
```

Use `SetValue<TValue>(string identifier, TValue value)` to update the value of the specified JS property synchronously. The property can't be a `get`-only property. If the property isn't defined on the target object, the property is created. A <xref:Microsoft.JSInterop.JSException> is thrown if the property exists but isn't writable or when a new property can't be added to the object. In the following example, `testObject.num` is set to 20, and `num2` is created with a value of 30 on `testObject`:

```csharp
var inProcRuntime = ((IJSInProcessRuntime)JSRuntime);
inProcRuntime.SetValue("testObject.num", 20);
inProcRuntime.SetValue("testObject.num2", 30);
```

:::moniker-end

## JavaScript location

Load JavaScript (JS) code using any of approaches described by the [article on JavaScript location](xref:blazor/js-interop/javascript-location):
Expand Down Expand Up @@ -519,12 +620,35 @@ For browser compatibility, see [Can I use: JavaScript modules: dynamic import](h

In server-side scenarios, JS interop calls can't be issued after Blazor's SignalR circuit is disconnected. Without a circuit during component disposal or at any other time that a circuit doesn't exist, the following method calls fail and log a message that the circuit is disconnected as a <xref:Microsoft.JSInterop.JSDisconnectedException>:

:::moniker-end

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

<!-- UPDATE 10.0 - API Browser cross-links -->

* JS interop method calls
* <xref:Microsoft.JSInterop.IJSRuntime.InvokeAsync%2A?displayProperty=nameWithType>
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeAsync%2A?displayProperty=nameWithType>
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync%2A?displayProperty=nameWithType>)
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync%2A?displayProperty=nameWithType>
* `InvokeNewAsync`
* `GetValueAsync`
* `SetValueAsync`
* `Dispose`/`DisposeAsync` calls on any <xref:Microsoft.JSInterop.IJSObjectReference>.

:::moniker-end

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

* JS interop method calls
* <xref:Microsoft.JSInterop.IJSRuntime.InvokeAsync%2A?displayProperty=nameWithType>
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeAsync%2A?displayProperty=nameWithType>
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync%2A?displayProperty=nameWithType>
* `Dispose`/`DisposeAsync` calls on any <xref:Microsoft.JSInterop.IJSObjectReference>.

:::moniker-end

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

In order to avoid logging <xref:Microsoft.JSInterop.JSDisconnectedException> or to log custom information in server-side Blazor, catch the exception in a [`try-catch`](/dotnet/csharp/language-reference/keywords/try-catch) statement.

For the following component disposal example:
Expand Down Expand Up @@ -627,7 +751,7 @@ In the preceding example:

Dynamically importing a module requires a network request, so it can only be achieved asynchronously by calling <xref:Microsoft.JSInterop.IJSRuntime.InvokeAsync%2A>.

`IJSInProcessObjectReference` represents a reference to a JS object whose functions can be invoked synchronously in client-side components. For more information, see the [Synchronous JS interop in client-side components](#synchronous-js-interop-in-client-side-components) section.
<xref:Microsoft.JSInterop.IJSInProcessObjectReference> represents a reference to a JS object whose functions can be invoked synchronously in client-side components. For more information, see the [Synchronous JS interop in client-side components](#synchronous-js-interop-in-client-side-components) section.

> [!NOTE]
> When the external JS file is supplied by a [Razor class library](xref:blazor/components/class-libraries), specify the module's JS file using its stable static web asset path: `./_content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}`:
Expand Down
19 changes: 19 additions & 0 deletions aspnetcore/blazor/javascript-interoperability/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,12 +328,31 @@ Don't assume that observing `document.body`, instead of `target.parentNode`, is

JavaScript (JS) interop calls can't be issued after Blazor's SignalR circuit is disconnected. Without a circuit during component disposal or at any other time that a circuit doesn't exist, the following method calls fail and log a message that the circuit is disconnected as a <xref:Microsoft.JSInterop.JSDisconnectedException>:

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

<!-- UPDATE 10.0 - API Browser cross-links -->

* JS interop method calls
* <xref:Microsoft.JSInterop.IJSRuntime.InvokeAsync%2A?displayProperty=nameWithType>
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeAsync%2A?displayProperty=nameWithType>
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync%2A?displayProperty=nameWithType>
* `InvokeNewAsync`
* `GetValueAsync`
* `SetValueAsync`
* `Dispose`/`DisposeAsync` calls on any <xref:Microsoft.JSInterop.IJSObjectReference>.

:::moniker-end

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

* JS interop method calls
* <xref:Microsoft.JSInterop.IJSRuntime.InvokeAsync%2A?displayProperty=nameWithType>
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeAsync%2A?displayProperty=nameWithType>
* <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync%2A?displayProperty=nameWithType>
* `Dispose`/`DisposeAsync` calls on any <xref:Microsoft.JSInterop.IJSObjectReference>.

:::moniker-end

In order to avoid logging <xref:Microsoft.JSInterop.JSDisconnectedException> or to log custom information, catch the exception in a [`try-catch`](/dotnet/csharp/language-reference/keywords/try-catch) statement.

For the following component disposal example:
Expand Down
17 changes: 9 additions & 8 deletions aspnetcore/blazor/tooling.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ To create a Blazor app with Visual Studio, use the following guidance:

* Create a new project using one of the available Blazor templates:

* **Blazor Web App**: Creates a Blazor web app that supports interactive server-side rendering (interactive SSR) and client-side rendering (CSR). The Blazor Web App template is recommended for getting started with Blazor to learn about server-side and client-side Blazor features.
* **Blazor Web App**: Creates an app that supports interactive server-side rendering (interactive SSR) and client-side rendering (CSR). The Blazor Web App template is recommended for getting started with Blazor to learn about server-side and client-side Blazor features.
* **Blazor WebAssembly Standalone App**: Creates a standalone client web app that can be deployed as a static site.

Select **Next**.
Expand Down Expand Up @@ -62,13 +62,6 @@ Select **Next**.

* For more information on the options in the **Additional information** dialog, see the [Blazor project templates and template options](#blazor-project-templates-and-template-options) section.

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

> [!NOTE]
> The Hosted Blazor WebAssembly project template isn't available in ASP.NET Core 8.0 or later. To create a hosted Blazor WebAssembly app, a **Framework** option earlier than .NET 8.0 must be selected with the **ASP.NET Core Hosted** checkbox.

:::moniker-end

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

* For a *hosted* Blazor WebAssembly app, select the **ASP.NET Core Hosted** checkbox in the **Additional information** dialog.
Expand Down Expand Up @@ -508,6 +501,14 @@ The Blazor framework provides project templates for creating new apps. The templ
* Blazor Web App project template: `blazor`
* Standalone Blazor WebAssembly app project template: `blazorwasm`

> [!NOTE]
> The "Hosted" Blazor WebAssembly project template option isn't available in ASP.NET Core 8.0 or later. To create a hosted Blazor WebAssembly app, a **Framework** option earlier than .NET 8.0 must be selected with the **ASP.NET Core Hosted** checkbox. However, we recommend a Blazor Web App for all new Blazor development in .NET 8 or later. For more information, see the following resources:
>
> * <xref:blazor/index#build-a-full-stack-web-app-with-blazor>
> * <xref:aspnetcore-8#new-blazor-web-app-template>
> * <xref:blazor/project-structure#blazor-web-app>
> * <xref:migration/70-to-80#convert-a-hosted-blazor-webassembly-app-into-a-blazor-web-app>

:::moniker-end

:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0"
Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/fundamentals/openapi/openapi-comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ uid: fundamentals/openapi/aspnet-openapi-xml

ASP.NET Core XML documentation processing extracts code comments automatically to populate API documentation, ensuring the code and documentation remain synchronized. Metadata from XML documentation comments is included in the generated OpenAPI document without requiring changes to the app code, as long as the project is configured to generate the XML documentation file. XML documentation comments are automatically detected in the application assembly and referenced assemblies with XML documentation enabled.

ASP.NET Core processes [XML documentation tags](https://learn.microsoft.com/dotnet/csharp/language-reference/xmldoc/recommended-tags) like: `<c>`, `<code>`, `<list>`, `<para>`, `<paramref>`, `<typeparamref>`, `<see>`, and `<seealso>`. For XML documentation tags that use references to other elements, like `<see cref="SomeOtherType">`, the implementation strips out the XML tag and maps the reference to plain text for inclusion in the OpenAPI document.
ASP.NET Core processes [XML documentation tags](/dotnet/csharp/language-reference/xmldoc/recommended-tags) like: `<c>`, `<code>`, `<list>`, `<para>`, `<paramref>`, `<typeparamref>`, `<see>`, and `<seealso>`. For XML documentation tags that use references to other elements, like `<see cref="SomeOtherType">`, the implementation strips out the XML tag and maps the reference to plain text for inclusion in the OpenAPI document.

ASP.NET Core XML documentation processing doesn't affect runtime performance. The source generator processes XML documentation at compile time and caches the results, with minimal runtime overhead when rendering the OpenAPI documentation. Furthermore, the OpenAPI document can be cached at runtime using [output-caching](/aspnet/core/performance/caching/overview#output-caching) to further optimize performance.

Expand Down
3 changes: 2 additions & 1 deletion aspnetcore/fundamentals/openapi/using-openapi-documents.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ The `Swashbuckle.AspNetCore.SwaggerUi` package provides a bundle of Swagger UI's

* Install the `Swashbuckle.AspNetCore.SwaggerUi` package.
* Enable the swagger-ui middleware with a reference to the [OpenAPI route registered earlier](xref:fundamentals/openapi/aspnetcore-openapi#customize-the-openapi-endpoint-route).
* To limit information disclosure and security vulnerability, ***only enable Swagger UI in development environments.***

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

As a security best practice on limiting information disclosure, ***OpenAPI user interfaces (Swagger UI, ReDoc, Scalar) should only be enabled in development environments.*** For example, see [Swagger OAuth 2.0 configuration](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/).

## Use Scalar for interactive API documentation

[Scalar](https://scalar.com/) is an open-source interactive document UI for OpenAPI. Scalar can integrate with the OpenAPI endpoint provided by ASP.NET Core. To configure Scalar, install the `Scalar.AspNetCore` package.
Expand Down
Loading
Loading