diff --git a/aspnetcore/blazor/project-structure.md b/aspnetcore/blazor/project-structure.md index d0c756746444..41502429aa01 100644 --- a/aspnetcore/blazor/project-structure.md +++ b/aspnetcore/blazor/project-structure.md @@ -42,7 +42,7 @@ Based on the interactive render mode selected at app creation, the `Layout` fold * The `NavMenu.razor.css` is the collocated stylesheet for the app's navigation menu. * The `ReconnectModal` component reflects the server-side connection state in the UI and is included when the app's interactive render mode is either Interactive Server or Interactive Auto. For more information, see . * The `ReconnectModal.razor.css` is the collocated stylesheet for the `ReconnectModal` component. -* The `ReconnectModal.razor.css` is the collocated JavaScript file for the `ReconnectModal` component. +* The `ReconnectModal.razor.js` is the collocated JavaScript file for the `ReconnectModal` component. :::moniker-end diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-1.md b/aspnetcore/blazor/tutorials/movie-database-app/part-1.md index ceaaff32c38c..62a5f6964374 100644 --- a/aspnetcore/blazor/tutorials/movie-database-app/part-1.md +++ b/aspnetcore/blazor/tutorials/movie-database-app/part-1.md @@ -231,6 +231,9 @@ The `Components/Layout` folder contains the following layout components and styl * `MainLayout.razor.css`: Stylesheet for the app's main layout. * `NavMenu` component (`NavMenu.razor`): Implements sidebar navigation. This component uses several `NavLink` components to render navigation links to other Razor components. * `NavMenu.razor.css`: Stylesheet for the app's navigation menu. +* `ReconnectModal` component (`ReconnectModal.razor`): Reflects the server-side connection state in the UI. +* `ReconnectModal.razor.css`: Stylesheet for the `ReconnectModal` component. +* `ReconnectModal.razor.js`: JavaScript file for the `ReconnectModal` component. ### `Components/_Imports.razor` file diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-3.md b/aspnetcore/blazor/tutorials/movie-database-app/part-3.md index 6edf58e124af..cf92eead8051 100644 --- a/aspnetcore/blazor/tutorials/movie-database-app/part-3.md +++ b/aspnetcore/blazor/tutorials/movie-database-app/part-3.md @@ -421,13 +421,31 @@ The `movie` variable is a private field of type `Movie`, which is a null-referen The `Id` is a *component parameter* supplied from the component's query string due to the presence of the [`[SupplyParameterFromQuery]` attribute](xref:Microsoft.AspNetCore.Components.SupplyParameterFromQueryAttribute). If the identifier is missing, `Id` defaults to zero (`0`). -`OnInitializedAsync` is the first component lifecycle method that we've seen. This method is executed when the component loads. is called on the database set (`DbSet`) to retrieve the movie entity with and `Id` equal to the `Id` parameter that was set by the query string. If `movie` is `null`, is used to navigate to a `notfound` endpoint. +`OnInitializedAsync` is the first component lifecycle method that we've seen. This method is executed when the component loads. is called on the database set (`DbSet`) to retrieve the movie entity with an `Id` equal to the `Id` parameter that was set by the query string. If `movie` is `null`, is used to navigate to a `notfound` endpoint. - + -There isn't an actual `notfound` endpoint (Razor component) in the app. When adopting server-side rendering (SSR), Blazor doesn't have a mechanism to return a 404 (Not Found) status code. As a temporary workaround, a 404 is generated by navigating to a non-existent endpoint. This scaffolded code is for your further implementation of a suitable result when not finding an entity. For example, you could have the component direct the user to a page where they can file an inquiry with your support team, or you could remove the injected and code and replace it with Razor markup and code that displays a message to the user that the entity wasn't found. +:::moniker range=">= aspnetcore-10.0" + +The .NET scaffolder currently doesn't implement .NET 10's Not Found feature, but it can be implemented manually. + +Update the line that navigates to a non-existent `notfound` endpoint. Change the line to call : + +```diff +- NavigationManager.NavigateTo("notfound"); ++ NavigationManager.NotFound(); +``` + +When a movie isn't found, this line change results in rendering the `NotFound` component, which produces a Not Found page in the browser with a 404 (Not Found) status code. + +:::moniker-end + +:::moniker range="< aspnetcore-10.0" + +There isn't an actual `notfound` endpoint (Razor component) in the app. When adopting server-side rendering (SSR) in .NET 8 or .NET 9, the app doesn't have a mechanism to return a 404 (Not Found) status code. A 404 is generated by navigating to a non-existent endpoint. This scaffolded code is for your further implementation of a suitable result when not finding an entity in .NET 8/9. For example, you could have the component direct the user to a page where they can file an inquiry with your support team, or you could remove the injected and code and replace it with Razor markup and code that displays a message to the user that the entity wasn't found. In .NET 10 or later, Blazor has a built-in Not Found feature. For more information, see the [.NET 10 version of this section](?view=aspnetcore-10.0&pivots=vs&preserve-view=true#details-component). + +:::moniker-end ### `Create` component @@ -540,6 +558,24 @@ private async Task DeleteMovie() } ``` + + +:::moniker range=">= aspnetcore-10.0" + +The .NET scaffolder currently doesn't implement .NET 10's Not Found feature, but it can be implemented manually. + +Update the line that navigates to a non-existent `notfound` endpoint. Change the line to call : + +```diff +- NavigationManager.NavigateTo("notfound"); ++ NavigationManager.NotFound(); +``` + +When a movie isn't found, this line change results in rendering the `NotFound` component, which produces a Not Found page in the browser with a 404 (Not Found) status code. + +:::moniker-end + ### `Edit` component Open the `Edit` component definition file (`Components/Pages/Movies/Edit.razor`). @@ -595,8 +631,32 @@ private bool MovieExists(int id) The movie entity's is set to , which signifies that the entity is tracked by the context, exists in the database, and that some or all of its property values are modified. + + +:::moniker range=">= aspnetcore-10.0" + +The .NET scaffolder currently doesn't implement .NET 10's Not Found feature, but it can be implemented manually. + +Update the line that navigates to a non-existent `notfound` endpoint. Change the line to call : + +```diff +- NavigationManager.NavigateTo("notfound"); ++ NavigationManager.NotFound(); +``` + +When a movie isn't found, this line change results in rendering the `NotFound` component, which produces a Not Found page in the browser with a 404 (Not Found) status code. + +If there's a concurrency exception and the movie entity no longer exists at the time that changes are saved, the component redirects to the Not Found page, which results in returning a 404 (Not Found) status code. If the movie exists and a concurrency exception is thrown, for example when another user has already modified the entity, the exception is rethrown by the component with the [`throw` statement (C# Language Reference)](/dotnet/csharp/language-reference/statements/exception-handling-statements#the-throw-statement). Additional guidance on handling concurrency with EF Core in Blazor apps is provided by the Blazor documentation. + +:::moniker-end + +:::moniker range="< aspnetcore-10.0" + If there's a concurrency exception and the movie entity no longer exists at the time that changes are saved, the component redirects to the non-existent endpoint (`notfound`), which results in returning a 404 (Not Found) status code. You could change this code to notify the user that the movie no longer exists in the database or create a dedicated *Not Found* component and navigate the user to that endpoint. If the movie exists and a concurrency exception is thrown, for example when another user has already modified the entity, the exception is rethrown by the component with the [`throw` statement (C# Language Reference)](/dotnet/csharp/language-reference/statements/exception-handling-statements#the-throw-statement). Additional guidance on handling concurrency with EF Core in Blazor apps is provided by the Blazor documentation. +:::moniker-end + > [!WARNING] > Although it isn't a concern for the app in this tutorial, binding form data to entity data models can be susceptible to overposting attacks. Additional information on this subject appears in the next section. diff --git a/aspnetcore/blazor/tutorials/movie-database-app/part-4.md b/aspnetcore/blazor/tutorials/movie-database-app/part-4.md index 25ff58c6c1ae..f75075520792 100644 --- a/aspnetcore/blazor/tutorials/movie-database-app/part-4.md +++ b/aspnetcore/blazor/tutorials/movie-database-app/part-4.md @@ -286,6 +286,47 @@ If the model state has errors when the form is posted, for example if `ReleaseDa Review the `UpdateMovie` method of the `Edit` component (`Components/Pages/MoviePages/Edit.razor`): +:::moniker range=">= aspnetcore-10.0" + +```csharp +private async Task UpdateMovie() +{ + using var context = DbFactory.CreateDbContext(); + context.Attach(Movie!).State = EntityState.Modified; + + try + { + await context.SaveChangesAsync(); + } + catch (DbUpdateConcurrencyException) + { + if (!MovieExists(Movie!.Id)) + { + NavigationManager.NotFound(); + } + else + { + throw; + } + } + + NavigationManager.NavigateTo("/movies"); +} +``` + +Concurrency exceptions are detected when one client deletes the movie and a different client posts changes to the movie. + +To test how concurrency is handled by the preceding code: + +1. Select **:::no-loc text="Edit":::** for a movie, make changes, but don't select **:::no-loc text="Save":::**. +1. In a different browser window, open the app to the movie `Index` page and select the **:::no-loc text="Delete":::** link for the same movie to delete the movie. +1. In the previous browser window, post changes to the movie by selecting the **:::no-loc text="Save":::** button. +1. The browser is navigated to the Not Found page with a 404 (Not Found) status code. + +:::moniker-end + +:::moniker range="< aspnetcore-10.0" + ```csharp private async Task UpdateMovie() { @@ -321,6 +362,8 @@ To test how concurrency is handled by the preceding code: 1. In the previous browser window, post changes to the movie by selecting the **:::no-loc text="Save":::** button. 1. The browser is navigated to the `notfound` endpoint, which doesn't exist and yields a 404 (Not Found) result. +:::moniker-end + Additional guidance on handling concurrency with EF Core in Blazor apps is available in the Blazor documentation. ## Stop the app diff --git a/aspnetcore/test/troubleshoot-azure-iis.md b/aspnetcore/test/troubleshoot-azure-iis.md index c246ea88783b..edee9c873f9d 100644 --- a/aspnetcore/test/troubleshoot-azure-iis.md +++ b/aspnetcore/test/troubleshoot-azure-iis.md @@ -5,7 +5,7 @@ description: Learn how to diagnose problems with Azure App Service and Internet monikerRange: '>= aspnetcore-2.1' ms.author: tdykstra ms.custom: mvc -ms.date: 7/23/2024 +ms.date: 11/13/2025 uid: test/troubleshoot-azure-iis --- # Troubleshoot ASP.NET Core on Azure App Service and IIS