Skip to content

Commit 604f7f9

Browse files
authored
Merge pull request #36648 from dotnet/main
Reviewd, approved and merged to live.
2 parents a0d61ce + 122dedd commit 604f7f9

173 files changed

Lines changed: 170765 additions & 287 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* [Visual Studio 2026](https://visualstudio.microsoft.com/downloads/) with the **ASP.NET and web development** workload.
2+
3+
:::image type="content" source="~/tutorials/min-web-api/_static/asp-net-web-dev-2026.png" alt-text="VS22 installer workloads" lightbox="~/tutorials/min-web-api/_static/asp-net-web-dev-2026.png":::
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
* [Visual Studio Code](https://code.visualstudio.com/download)
22
* [C# Dev Kit for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit)
3-
* [!INCLUDE [](~/includes/0-latest-SDK.md)]
3+
* [!INCLUDE [](~/includes/10.0-SDK.md)]
44

55
You can follow the Visual Studio Code instructions on macOS, Linux, or Windows. Changes may be required if you use an integrated development environment (IDE) other than Visual Studio Code.
220 KB
Loading

aspnetcore/tutorials/razor-pages/da1.md

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,25 @@ title: Part 5, update the generated pages
33
author: wadepickett
44
description: Part 5 of tutorial series on Razor Pages.
55
ms.author: wpickett
6-
ms.date: 06/23/2024
6+
ms.date: 01/08/2026
77
uid: tutorials/razor-pages/da1
88
---
99
# Part 5, update the generated pages in an ASP.NET Core app
1010

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

13-
:::moniker range=">= aspnetcore-9.0"
13+
:::moniker range=">= aspnetcore-10.0"
1414

15-
The scaffolded movie app has a good start, but the presentation isn't ideal. **ReleaseDate** should be two words, **Release Date**.
15+
The scaffolded movie app is a good start, but the presentation isn't ideal. **ReleaseDate** should be two words, **Release Date**.
16+
17+
:::image type="content" source="~/tutorials/razor-pages/sql/media/seed-data-in-app.png" alt-text="Movie application open in Chrome.":::
1618

17-
![Movie application open in Chrome](~/tutorials/razor-pages/sql/_static/9/seededDataUI.png)
1819

1920
## Update the model
2021

2122
Update `Models/Movie.cs` with the following highlighted code:
2223

23-
[!code-csharp[Main](~/tutorials/razor-pages/razor-pages-start/snapshot_sample9/Models/MovieDateFixed.cs?name=snippet_1&highlight=2,11,16)]
24+
[!code-csharp[Main](~/tutorials/razor-pages/razor-pages-start/snapshot-sample10/Models/MovieDateFixed.cs?name=snippet_1&highlight=2,11,16)]
2425

2526
In the previous code:
2627

@@ -32,11 +33,11 @@ In the previous code:
3233

3334
Browse to *Pages/Movies* and hover over an **Edit** link to see the target URL.
3435

35-
![Browser window with mouse over the Edit link and a link Url of https://localhost:1234/Movies/Edit/5 is shown](~/tutorials/razor-pages/da1/_static/9/edit9.png)
36+
:::image type="content" source="~/tutorials/razor-pages/da1/media/edit-movie.png" alt-text="Browser window with mouse over the Edit link and a link Url of https://localhost:1234/Movies/Edit/5 is shown.":::
3637

3738
The **Edit**, **Details**, and **Delete** links are generated by the [Anchor Tag Helper](xref:mvc/views/tag-helpers/builtin-th/anchor-tag-helper) in the `Pages/Movies/Index.cshtml` file.
3839

39-
[!code-cshtml[](~/tutorials/razor-pages/razor-pages-start/snapshot_sample9/Pages/Movies/Index.cshtml?highlight=16-18&range=32-)]
40+
[!code-cshtml[](~/tutorials/razor-pages/razor-pages-start/snapshot-sample10/Pages/Movies/Index.cshtml?highlight=16-18&range=32-)]
4041

4142
[Tag Helpers](xref:mvc/views/tag-helpers/intro) enable server-side code to participate in creating and rendering HTML elements in Razor files.
4243

@@ -52,7 +53,7 @@ Use **View Source** from a browser to examine the generated markup. A portion of
5253
</td>
5354
```
5455

55-
The dynamically generated links pass the movie ID with a [query string](https://launchschool.com/books/http/read/what_is_a_url). For example, the `?id=1` in `https://localhost:5001/Movies/Details?id=1`.
56+
The dynamically generated links pass the movie ID with a [query string](https://launchschool.com/books/http/read/what_is_a_url). For example, the `?id=1` in `https://localhost:7247/Movies/Details?id=1`.
5657

5758
### Add route template
5859

@@ -68,7 +69,7 @@ The generated HTML adds the ID to the path portion of the URL:
6869
</td>
6970
```
7071

71-
A request to the page with the `{id:int}` route template that does **not** include the integer returns an HTTP 404 (not found) error. For example, `https://localhost:5001/Movies/Details` returns a 404 error. To make the ID optional, append `?` to the route constraint:
72+
A request to the page with the `{id:int}` route template that doesn't include the integer returns an HTTP 404 (not found) error. For example, `https://localhost:7247/Movies/Details` returns a 404 error. To make the ID optional, append `?` to the route constraint:
7273

7374
```cshtml
7475
@page "{id:int?}"
@@ -78,51 +79,51 @@ Test the behavior of `@page "{id:int?}"`:
7879

7980
1. Set the page directive in `Pages/Movies/Details.cshtml` to `@page "{id:int?}"`.
8081
1. Set a break point in `public async Task<IActionResult> OnGetAsync(int? id)`, in `Pages/Movies/Details.cshtml.cs`.
81-
1. Navigate to `https://localhost:5001/Movies/Details/`.
82+
1. Navigate to `https://localhost:7247/Movies/Details/`.
8283

8384
With the `@page "{id:int}"` directive, the break point is never hit. The routing engine returns HTTP 404. Using `@page "{id:int?}"`, the `OnGetAsync` method returns `NotFound` (HTTP 404):
8485

85-
[!code-csharp[](~/tutorials/razor-pages/razor-pages-start/snapshot_sample9/Pages/Movies/Details.cshtml.cs?name=snippet_1&highlight=3-6)]
86+
[!code-csharp[](~/tutorials/razor-pages/razor-pages-start/snapshot-sample10/Pages/Movies/Details.cshtml.cs?name=snippet_1&highlight=3-6)]
8687

8788
### Review concurrency exception handling
8889

8990
Review the `OnPostAsync` method in the `Pages/Movies/Edit.cshtml.cs` file:
9091

91-
[!code-csharp[](~/tutorials/razor-pages/razor-pages-start/snapshot_sample9/Pages/Movies/Edit.cshtml.cs?name=snippet_1)]
92+
[!code-csharp[](~/tutorials/razor-pages/razor-pages-start/snapshot-sample10/Pages/Movies/Edit.cshtml.cs?name=snippet_1)]
9293

9394
The previous code detects concurrency exceptions when one client deletes the movie and the other client posts changes to the movie.
9495

9596
To test the `catch` block:
9697

9798
1. Set a breakpoint on `catch (DbUpdateConcurrencyException)`.
98-
1. Select **Edit** for a movie, make changes, but don't enter **Save**.
99+
1. Select **Edit** for a movie, make changes, but don't select **Save**.
99100
1. In another browser window, select the **Delete** link for the same movie, and then delete the movie.
100101
1. In the previous browser window, post changes to the movie.
101102

102-
Production code may want to detect concurrency conflicts. See [Handle concurrency conflicts](xref:data/ef-rp/concurrency) for more information.
103+
Production code might want to detect concurrency conflicts. For more information, see [Handle concurrency conflicts](xref:data/ef-rp/concurrency).
103104

104105
### Posting and binding review
105106

106107
Examine the `Pages/Movies/Edit.cshtml.cs` file:
107108

108-
[!code-csharp[](~/tutorials/razor-pages/razor-pages-start/snapshot_sample9/Pages/Movies/Edit.cshtml.cs?name=snippet2)]
109+
[!code-csharp[](~/tutorials/razor-pages/razor-pages-start/snapshot-sample10/Pages/Movies/Edit.cshtml.cs?name=snippet2)]
109110

110-
When an HTTP GET request is made to the Movies/Edit page, for example, `https://localhost:5001/Movies/Edit/3`:
111+
When you make an HTTP GET request to the `Movies/Edit` page, for example, `https://localhost:7247/Movies/Edit/3`:
111112

112113
* The `OnGetAsync` method fetches the movie from the database and returns the `Page` method.
113114
* The `Page` method renders the `Pages/Movies/Edit.cshtml` Razor Page. The `Pages/Movies/Edit.cshtml` file contains the model directive `@model RazorPagesMovie.Pages.Movies.EditModel`, which makes the movie model available on the page.
114-
* The Edit form is displayed with the values from the movie.
115+
* The Edit form displays the values from the movie.
115116

116-
When the Movies/Edit page is posted:
117+
When you post the `Movies/Edit` page:
117118

118-
* The form values on the page are bound to the `Movie` property. The `[BindProperty]` attribute enables [Model binding](xref:mvc/models/model-binding).
119+
* The form values on the page bind to the `Movie` property. The `[BindProperty]` attribute enables [Model binding](xref:mvc/models/model-binding).
119120

120121
```csharp
121122
[BindProperty]
122123
public Movie Movie { get; set; }
123124
```
124125

125-
* If there are errors in the model state, for example, `ReleaseDate` cannot be converted to a date, the form is redisplayed with the submitted values.
126+
* If there are errors in the model state, for example, `ReleaseDate` can't convert to a date, the form redisplays with the submitted values.
126127
* If there are no model errors, the movie is saved.
127128

128129
The HTTP GET methods in the Index, Create, and Delete Razor pages follow a similar pattern. The HTTP POST `OnPostAsync` method in the Create Razor Page follows a similar pattern to the `OnPostAsync` method in the Edit Razor Page.
@@ -135,6 +136,8 @@ The HTTP GET methods in the Index, Create, and Delete Razor pages follow a simil
135136
136137
:::moniker-end
137138

139+
[!INCLUDE[](~/tutorials/razor-pages/da1/includes/da1-9.md)]
140+
138141
[!INCLUDE[](~/tutorials/razor-pages/da1/includes/da1_8.md)]
139142

140143
[!INCLUDE[](~/tutorials/razor-pages/da1/includes/da1_7.md)]
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
:::moniker range="= aspnetcore-9.0"
2+
3+
The scaffolded movie app has a good start, but the presentation isn't ideal. **ReleaseDate** should be two words, **Release Date**.
4+
5+
![Movie application open in Chrome](~/tutorials/razor-pages/sql/_static/9/seededDataUI.png)
6+
7+
## Update the model
8+
9+
Update `Models/Movie.cs` with the following highlighted code:
10+
11+
[!code-csharp[Main](~/tutorials/razor-pages/razor-pages-start/snapshot_sample9/Models/MovieDateFixed.cs?name=snippet_1&highlight=2,11,16)]
12+
13+
In the previous code:
14+
15+
* The `[Column(TypeName = "decimal(18, 2)")]` data annotation enables Entity Framework Core to correctly map `Price` to currency in the database. For more information, see [Data Types](/ef/core/modeling/relational/data-types).
16+
* The [[Display]](xref:System.ComponentModel.DataAnnotations.DisplayAttribute) attribute specifies the display name of a field. In the preceding code, `Release Date` instead of `ReleaseDate`.
17+
* The [[DataType]](xref:System.ComponentModel.DataAnnotations.DataTypeAttribute) attribute specifies the type of the data (`Date`). The time information stored in the field isn't displayed.
18+
19+
[DataAnnotations](/aspnet/mvc/overview/older-versions/mvc-music-store/mvc-music-store-part-6) is covered in the next tutorial.
20+
21+
Browse to *Pages/Movies* and hover over an **Edit** link to see the target URL.
22+
23+
![Browser window with mouse over the Edit link and a link Url of https://localhost:1234/Movies/Edit/5 is shown](~/tutorials/razor-pages/da1/_static/9/edit9.png)
24+
25+
The **Edit**, **Details**, and **Delete** links are generated by the [Anchor Tag Helper](xref:mvc/views/tag-helpers/builtin-th/anchor-tag-helper) in the `Pages/Movies/Index.cshtml` file.
26+
27+
[!code-cshtml[](~/tutorials/razor-pages/razor-pages-start/snapshot_sample9/Pages/Movies/Index.cshtml?highlight=16-18&range=32-)]
28+
29+
[Tag Helpers](xref:mvc/views/tag-helpers/intro) enable server-side code to participate in creating and rendering HTML elements in Razor files.
30+
31+
In the preceding code, the [Anchor Tag Helper](xref:mvc/views/tag-helpers/builtin-th/anchor-tag-helper) dynamically generates the HTML `href` attribute value from the Razor Page (the route is relative), the `asp-page`, and the route identifier (`asp-route-id`). For more information, see [URL generation for Pages](xref:razor-pages/index#url-generation-for-pages).
32+
33+
Use **View Source** from a browser to examine the generated markup. A portion of the generated HTML is shown below:
34+
35+
```html
36+
<td>
37+
<a href="/Movies/Edit?id=1">Edit</a> |
38+
<a href="/Movies/Details?id=1">Details</a> |
39+
<a href="/Movies/Delete?id=1">Delete</a>
40+
</td>
41+
```
42+
43+
The dynamically generated links pass the movie ID with a [query string](https://launchschool.com/books/http/read/what_is_a_url). For example, the `?id=1` in `https://localhost:5001/Movies/Details?id=1`.
44+
45+
### Add route template
46+
47+
Update the Edit, Details, and Delete Razor Pages to use the `{id:int}` route template. Change the page directive for each of these pages from `@page` to `@page "{id:int}"`. Run the app and then view source.
48+
49+
The generated HTML adds the ID to the path portion of the URL:
50+
51+
```html
52+
<td>
53+
<a href="/Movies/Edit/1">Edit</a> |
54+
<a href="/Movies/Details/1">Details</a> |
55+
<a href="/Movies/Delete/1">Delete</a>
56+
</td>
57+
```
58+
59+
A request to the page with the `{id:int}` route template that does **not** include the integer returns an HTTP 404 (not found) error. For example, `https://localhost:5001/Movies/Details` returns a 404 error. To make the ID optional, append `?` to the route constraint:
60+
61+
```cshtml
62+
@page "{id:int?}"
63+
```
64+
65+
Test the behavior of `@page "{id:int?}"`:
66+
67+
1. Set the page directive in `Pages/Movies/Details.cshtml` to `@page "{id:int?}"`.
68+
1. Set a break point in `public async Task<IActionResult> OnGetAsync(int? id)`, in `Pages/Movies/Details.cshtml.cs`.
69+
1. Navigate to `https://localhost:5001/Movies/Details/`.
70+
71+
With the `@page "{id:int}"` directive, the break point is never hit. The routing engine returns HTTP 404. Using `@page "{id:int?}"`, the `OnGetAsync` method returns `NotFound` (HTTP 404):
72+
73+
[!code-csharp[](~/tutorials/razor-pages/razor-pages-start/snapshot_sample9/Pages/Movies/Details.cshtml.cs?name=snippet_1&highlight=3-6)]
74+
75+
### Review concurrency exception handling
76+
77+
Review the `OnPostAsync` method in the `Pages/Movies/Edit.cshtml.cs` file:
78+
79+
[!code-csharp[](~/tutorials/razor-pages/razor-pages-start/snapshot_sample9/Pages/Movies/Edit.cshtml.cs?name=snippet_1)]
80+
81+
The previous code detects concurrency exceptions when one client deletes the movie and the other client posts changes to the movie.
82+
83+
To test the `catch` block:
84+
85+
1. Set a breakpoint on `catch (DbUpdateConcurrencyException)`.
86+
1. Select **Edit** for a movie, make changes, but don't enter **Save**.
87+
1. In another browser window, select the **Delete** link for the same movie, and then delete the movie.
88+
1. In the previous browser window, post changes to the movie.
89+
90+
Production code may want to detect concurrency conflicts. See [Handle concurrency conflicts](xref:data/ef-rp/concurrency) for more information.
91+
92+
### Posting and binding review
93+
94+
Examine the `Pages/Movies/Edit.cshtml.cs` file:
95+
96+
[!code-csharp[](~/tutorials/razor-pages/razor-pages-start/snapshot_sample9/Pages/Movies/Edit.cshtml.cs?name=snippet2)]
97+
98+
When an HTTP GET request is made to the Movies/Edit page, for example, `https://localhost:5001/Movies/Edit/3`:
99+
100+
* The `OnGetAsync` method fetches the movie from the database and returns the `Page` method.
101+
* The `Page` method renders the `Pages/Movies/Edit.cshtml` Razor Page. The `Pages/Movies/Edit.cshtml` file contains the model directive `@model RazorPagesMovie.Pages.Movies.EditModel`, which makes the movie model available on the page.
102+
* The Edit form is displayed with the values from the movie.
103+
104+
When the Movies/Edit page is posted:
105+
106+
* The form values on the page are bound to the `Movie` property. The `[BindProperty]` attribute enables [Model binding](xref:mvc/models/model-binding).
107+
108+
```csharp
109+
[BindProperty]
110+
public Movie Movie { get; set; }
111+
```
112+
113+
* If there are errors in the model state, for example, `ReleaseDate` cannot be converted to a date, the form is redisplayed with the submitted values.
114+
* If there are no model errors, the movie is saved.
115+
116+
The HTTP GET methods in the Index, Create, and Delete Razor pages follow a similar pattern. The HTTP POST `OnPostAsync` method in the Create Razor Page follows a similar pattern to the `OnPostAsync` method in the Edit Razor Page.
117+
118+
## Next steps
119+
120+
> [!div class="step-by-step"]
121+
> [Previous: Work with a database](xref:tutorials/razor-pages/sql)
122+
> [Next: Add search](xref:tutorials/razor-pages/search)
123+
124+
:::moniker-end
68.9 KB
Loading

aspnetcore/tutorials/razor-pages/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "Tutorial: Create a Razor Pages web app with ASP.NET Core"
33
author: wadepickett
44
description: This series of tutorials explains the basics of building a Razor Pages web app.
55
ms.author: wpickett
6-
ms.date: 06/23/2024
6+
ms.date: 01/09/2026
77
monikerRange: '>= aspnetcore-3.1'
88
uid: tutorials/razor-pages/index
99
---
@@ -30,6 +30,6 @@ This series includes the following tutorials:
3030

3131
At the end, you'll have an app that can display and manage a database of movies.
3232

33-
![Sample page of sample app](~/tutorials/razor-pages/index/_static/sample-page.png)
33+
:::image type="content" source="~/tutorials/razor-pages/search/media/search-string-ghost.png" alt-text="Sample page of sample app.":::
3434

35-
![Sample edit validation of sample app](~/tutorials/razor-pages/index/_static/sample-page-validation.png)
35+
:::image type="content" source="~/tutorials/razor-pages/validation/media/validation-errors.png" alt-text="Sample edit validation of sample app.":::

0 commit comments

Comments
 (0)