diff --git a/aspnetcore/blazor/components/data-binding.md b/aspnetcore/blazor/components/data-binding.md index a2b21f1eae5e..c0854b726b9d 100644 --- a/aspnetcore/blazor/components/data-binding.md +++ b/aspnetcore/blazor/components/data-binding.md @@ -221,14 +221,14 @@ Additional examples For more information on the `InputText` component, see . -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`: @@ -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 returned by . 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 returned by 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 returned by 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 returned by . 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 returned by . 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 @@ -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 returned by 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`: diff --git a/aspnetcore/blazor/globalization-localization.md b/aspnetcore/blazor/globalization-localization.md index 50c3e0cb063a..4090589e4f44 100644 --- a/aspnetcore/blazor/globalization-localization.md +++ b/aspnetcore/blazor/globalization-localization.md @@ -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 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 diff --git a/aspnetcore/blazor/host-and-deploy/index.md b/aspnetcore/blazor/host-and-deploy/index.md index 8b784bf8b4a4..15199f609669 100644 --- a/aspnetcore/blazor/host-and-deploy/index.md +++ b/aspnetcore/blazor/host-and-deploy/index.md @@ -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: @@ -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" diff --git a/aspnetcore/blazor/hybrid/index.md b/aspnetcore/blazor/hybrid/index.md index 5c2891312a8c..739bba5eac2f 100644 --- a/aspnetcore/blazor/hybrid/index.md +++ b/aspnetcore/blazor/hybrid/index.md @@ -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 using , 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" diff --git a/aspnetcore/blazor/hybrid/security/index.md b/aspnetcore/blazor/hybrid/security/index.md index 925ee1ce00be..62c645593eaf 100644 --- a/aspnetcore/blazor/hybrid/security/index.md +++ b/aspnetcore/blazor/hybrid/security/index.md @@ -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: @@ -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: diff --git a/aspnetcore/blazor/hybrid/tutorials/maui.md b/aspnetcore/blazor/hybrid/tutorials/maui.md index b40b7445787d..5d3e694a1064 100644 --- a/aspnetcore/blazor/hybrid/tutorials/maui.md +++ b/aspnetcore/blazor/hybrid/tutorials/maui.md @@ -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. @@ -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: diff --git a/aspnetcore/blazor/includes/js-interop/synchronous-js-interop-call-js.md b/aspnetcore/blazor/includes/js-interop/synchronous-js-interop-call-js.md index 98480a1163b4..f113355e985f 100644 --- a/aspnetcore/blazor/includes/js-interop/synchronous-js-interop-call-js.md +++ b/aspnetcore/blazor/includes/js-interop/synchronous-js-interop-call-js.md @@ -24,7 +24,7 @@ When working with in ASP.NET Core ```razor @inject IJSRuntime JS -@implements IAsyncDisposable +@implements IDisposable ... @@ -36,18 +36,20 @@ When working with in ASP.NET Core { if (firstRender) { - module = await JS.InvokeAsync("import", - "./scripts.js"); + var jsInProcess = (IJSInProcessRuntime)JS; + module = await jsInProcess.Invoke("import", + "./scripts.js"); + var value = module.Invoke("javascriptFunctionIdentifier"); } } ... - async ValueTask IAsyncDisposable.DisposeAsync() + void IDisposable.Dispose() { if (module is not null) { - await module.DisposeAsync(); + await module.Dispose(); } } } diff --git a/aspnetcore/blazor/index.md b/aspnetcore/blazor/index.md index eb9cf88c497a..28496a2ce329 100644 --- a/aspnetcore/blazor/index.md +++ b/aspnetcore/blazor/index.md @@ -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 . diff --git a/aspnetcore/blazor/security/blazor-web-app-with-oidc.md b/aspnetcore/blazor/security/blazor-web-app-with-oidc.md index b7e3e09e0f2b..5be8951bdc8c 100644 --- a/aspnetcore/blazor/security/blazor-web-app-with-oidc.md +++ b/aspnetcore/blazor/security/blazor-web-app-with-oidc.md @@ -654,6 +654,22 @@ The important changes to the `LogInOrOut` component are demonstrated in the foll ``` +:::moniker range="< aspnetcore-10.0" + +## Token refresh + + + +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). diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-1/_static/stop-button.png b/aspnetcore/blazor/tutorials/movie-database-app/part-1/_static/stop-button.png index 71630961b96a..62d84b09b3d1 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-1/_static/stop-button.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-1/_static/stop-button.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/add-new-scaffolded-item.png b/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/add-new-scaffolded-item.png index 2b0699d8eb6b..d06d8a30ed6d 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/add-new-scaffolded-item.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/add-new-scaffolded-item.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/add-razor-components-using-ef-crud.png b/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/add-razor-components-using-ef-crud.png index 034c5eacbe4b..a0a17e2b4534 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/add-razor-components-using-ef-crud.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/add-razor-components-using-ef-crud.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/create-new.png b/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/create-new.png index f07d84675574..4598fc374d8f 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/create-new.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/create-new.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/movie-added.png b/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/movie-added.png index d093dc03ebfd..237af8c77a9e 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/movie-added.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/movie-added.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/new-scaffolded-item.png b/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/new-scaffolded-item.png index 72e9e311690e..cc03b6d22d5a 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/new-scaffolded-item.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-2/_static/new-scaffolded-item.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-3/_static/updated-brand-and-added-link.png b/aspnetcore/blazor/tutorials/movie-database-app/part-3/_static/updated-brand-and-added-link.png index a15be30a7c8c..3ae78edab101 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-3/_static/updated-brand-and-added-link.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-3/_static/updated-brand-and-added-link.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-4/_static/index-page.png b/aspnetcore/blazor/tutorials/movie-database-app/part-4/_static/index-page.png index c7212fe8e83c..b33998536ba1 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-4/_static/index-page.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-4/_static/index-page.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-4/_static/view-ssox.png b/aspnetcore/blazor/tutorials/movie-database-app/part-4/_static/view-ssox.png index 54a90fa2cc66..dfbd786171fa 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-4/_static/view-ssox.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-4/_static/view-ssox.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/before-filtering.png b/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/before-filtering.png index 759d5670e181..8450c3b9ae45 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/before-filtering.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/before-filtering.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/form-filter-result.png b/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/form-filter-result.png index 4024d5639cc1..9158aee80c39 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/form-filter-result.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/form-filter-result.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/form-filter.png b/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/form-filter.png index ad5d39d4f05d..3e96c1c9c6af 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/form-filter.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/form-filter.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/query-string-filter-result.png b/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/query-string-filter-result.png index 01dc3affd885..a740eb6a3a94 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/query-string-filter-result.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-6/_static/query-string-filter-result.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/filtered-to-road-warrior.png b/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/filtered-to-road-warrior.png index 02ca3e0f5f0b..ad2bc99eac44 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/filtered-to-road-warrior.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/filtered-to-road-warrior.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/paging-movies.png b/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/paging-movies.png index a7fbc9d55441..a780c3f0eb15 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/paging-movies.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/paging-movies.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/sorted-movies.png b/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/sorted-movies.png index 0270d8489eeb..3d399c178c86 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/sorted-movies.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/sorted-movies.png differ diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/styled-quickgrid.png b/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/styled-quickgrid.png index 410a8e834f63..cb1308dbe159 100644 Binary files a/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/styled-quickgrid.png and b/aspnetcore/blazor/tutorials/movie-database-app/part-8/_static/styled-quickgrid.png differ diff --git a/aspnetcore/fundamentals/openapi/using-openapi-documents.md b/aspnetcore/fundamentals/openapi/using-openapi-documents.md index da6b30c509cf..d087b758cd13 100644 --- a/aspnetcore/fundamentals/openapi/using-openapi-documents.md +++ b/aspnetcore/fundamentals/openapi/using-openapi-documents.md @@ -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:/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). diff --git a/aspnetcore/tutorials/first-mvc-app/details.md b/aspnetcore/tutorials/first-mvc-app/details.md index 482288cb083a..0d5dd0922e9b 100644 --- a/aspnetcore/tutorials/first-mvc-app/details.md +++ b/aspnetcore/tutorials/first-mvc-app/details.md @@ -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"