You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add .NET 10 and Visual Studio 2026 moniker section to Razor Pages tutorial (#36590)
* Initial plan
* Add .NET 10 and Visual Studio 2026 support to Razor Pages tutorial
Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com>
* update screenshots
* fix filename
* Update all tutorials for Create a Razor Pages web app
* update wwwroot code
* restore validation-package-net10
* add RazorPagesSampleMovie10
* fix invalid file link
* attempt to update LICENSE.md contents
* change extension of LICENSE files from md to txt
* attempt to fix build warnings in folder and file names
* fix broken image link
* fix image link for edit movie screenshot
* change LICENSE file extension from .txt to .md
* edit pass
* fix code snippet links
* Fix syntax error in Razor Pages sample code
* update markdown image to Learn format to include border by default.
* use dark mode for VS2026 images
* extra cleanup
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com>
Co-authored-by: Meaghan Osagie <mosagie@microsoft.com>
*[Visual Studio Code](https://code.visualstudio.com/download)
2
2
*[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)]
4
4
5
5
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.
Browse to *Pages/Movies* and hover over an **Edit** link to see the target URL.
34
35
35
-

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.":::
36
37
37
38
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.
[Tag Helpers](xref:mvc/views/tag-helpers/intro) enable server-side code to participate in creating and rendering HTML elements in Razor files.
42
43
@@ -52,7 +53,7 @@ Use **View Source** from a browser to examine the generated markup. A portion of
52
53
</td>
53
54
```
54
55
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`.
56
57
57
58
### Add route template
58
59
@@ -68,7 +69,7 @@ The generated HTML adds the ID to the path portion of the URL:
68
69
</td>
69
70
```
70
71
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:
72
73
73
74
```cshtml
74
75
@page "{id:int?}"
@@ -78,51 +79,51 @@ Test the behavior of `@page "{id:int?}"`:
78
79
79
80
1. Set the page directive in `Pages/Movies/Details.cshtml` to `@page "{id:int?}"`.
80
81
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/`.
82
83
83
84
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):
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`:
111
112
112
113
* The `OnGetAsync` method fetches the movie from the database and returns the `Page` method.
113
114
* 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.
115
116
116
-
When the Movies/Edit page is posted:
117
+
When you post the `Movies/Edit` page:
117
118
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).
119
120
120
121
```csharp
121
122
[BindProperty]
122
123
publicMovieMovie { get; set; }
123
124
```
124
125
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.
126
127
* If there are no model errors, the movie is saved.
127
128
128
129
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
* 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
+

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.
[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
+
<ahref="/Movies/Edit?id=1">Edit</a> |
38
+
<ahref="/Movies/Details?id=1">Details</a> |
39
+
<ahref="/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
+
<ahref="/Movies/Edit/1">Edit</a> |
54
+
<ahref="/Movies/Details/1">Details</a> |
55
+
<ahref="/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):
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
+
publicMovieMovie { 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)
0 commit comments