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
2 changes: 1 addition & 1 deletion .github/workflows/docs-verifier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Validate
uses: dotnet/docs-actions/docs-verifier@ee93453f8ce383d3fdf0d1028ea57ba88ea2ad24 # main
uses: dotnet/docs-actions/docs-verifier@0423860a660ff661db5dbfef394d3f6da721d4c0 # main
env:
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4 changes: 2 additions & 2 deletions aspnetcore/grpc/json-transcoding.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ gRPC can still be used to call services.

1. Annotate gRPC methods in your `.proto` files with HTTP bindings and routes:

[!code-protobuf[](~/grpc/json-transcoding/samples/8/GrpcServiceTranscoding/protos/greet.proto?highlight=4,11-13)]
[!code-protobuf[](~/grpc/json-transcoding/samples/8/GrpcServiceTranscoding/Protos/greet.proto?highlight=4,11-13)]

The `SayHello` gRPC method can now be invoked as gRPC and as a JSON Web API:

Expand All @@ -69,7 +69,7 @@ info: Microsoft.AspNetCore.Hosting.Diagnostics[2]

gRPC methods must be annotated with an HTTP rule before they support transcoding. The HTTP rule includes information about how to call the gRPC method, such as the HTTP method and route.

[!code-protobuf[](~/grpc/json-transcoding/samples/8/GrpcServiceTranscoding/protos/greet.proto?highlight=3-5&range=9-15)]
[!code-protobuf[](~/grpc/json-transcoding/samples/8/GrpcServiceTranscoding/Protos/greet.proto?highlight=3-5&range=9-15)]

The proceeding example:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
ai-usage: ai-assisted
ms.date: 10/15/2026
---

:::moniker range="= aspnetcore-7.0"

[gRPC](https://grpc.io) is a high-performance Remote Procedure Call (RPC) framework. gRPC uses HTTP/2, streaming, Protobuf, and message contracts to create high-performance, real-time services.
Expand Down Expand Up @@ -27,7 +32,7 @@ gRPC can still be used to call services.
1. Add [`google/api/http.proto`](https://github.com/dotnet/aspnetcore/blob/main/src/Grpc/JsonTranscoding/test/testassets/Sandbox/google/api/http.proto) and [`google/api/annotations.proto`](https://github.com/dotnet/aspnetcore/blob/main/src/Grpc/JsonTranscoding/test/testassets/Sandbox/google/api/annotations.proto) files to the `/google/api` directory.
1. Annotate gRPC methods in your `.proto` files with HTTP bindings and routes:

[!code-protobuf[](~/grpc/json-transcoding/samples/7/GrpcServiceTranscoding/protos/greet.proto?highlight=4,11-13)]
[!code-protobuf[](~/grpc/json-transcoding/samples/7/GrpcServiceTranscoding/Protos/greet.proto?highlight=4,11-13)]

The `SayHello` gRPC method can now be invoked as gRPC and as a JSON Web API:

Expand All @@ -53,7 +58,7 @@ info: Microsoft.AspNetCore.Hosting.Diagnostics[2]

gRPC methods must be annotated with an HTTP rule before they support transcoding. The HTTP rule includes information about how to call the gRPC method, such as the HTTP method and route.

[!code-protobuf[](~/grpc/json-transcoding/samples/7/GrpcServiceTranscoding/protos/greet.proto?highlight=3-5&range=9-15)]
[!code-protobuf[](~/grpc/json-transcoding/samples/7/GrpcServiceTranscoding/Protos/greet.proto?highlight=3-5&range=9-15)]

The proceeding example:

Expand Down
4 changes: 2 additions & 2 deletions aspnetcore/includes/trustCertMac6.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Visual Studio for Mac displays the following popup:

![HTTPS Development certificate not found. Do you want to install and trust the certificate?](~/static/trustCertMac6.png)
![HTTPS Development certificate not found. Do you want to install and trust the certificate?](~/static/trustcertmac6.png)

Select **Install and Trust** if you trust the development certificate.

The following dialog is displayed:

![Security warning dialog](~/static/certMac6.png)
![Security warning dialog](~/static/certmac6.png)

Enter your password and select **Update Settings**

Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/markdown-links-verifier-config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"excludeStartingWith": [
"xref:",
"~/",
"~/../",
Comment thread
gewarren marked this conversation as resolved.
Resolved
"/",
"#-",
"?view",
Expand Down
6 changes: 3 additions & 3 deletions aspnetcore/tutorials/first-mvc-app/adding-controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: Part 2, add a controller to an ASP.NET Core MVC app
ai-usage: ai-assisted
description: Part 2 of tutorial series on ASP.NET Core MVC.
ms.date: 09/06/2026
monikerRange: '>= aspnetcore-3.1'
ms.date: 09/06/2026
uid: tutorials/first-mvc-app/adding-controller
---

Expand Down Expand Up @@ -59,7 +59,7 @@ Select the **EXPLORER** icon and then control-click (right-click) **Controllers

Replace the contents of `Controllers/HelloWorldController.cs` with the following code:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie10/Controllers/HelloWorldController.cs?name=snippet_First)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie10/Controllers/HelloWorldController.cs?name=snippet_First)]

Every `public` method in a controller is callable as an HTTP endpoint. In the sample above, both methods return a string. Note the comments preceding each method.

Expand Down Expand Up @@ -105,7 +105,7 @@ Modify the code to pass some parameter information from the URL to the controlle

Change the `Welcome` method to include two parameters as shown in the following code.

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie10/Controllers/HelloWorldController.cs?name=snippet_Second)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie10/Controllers/HelloWorldController.cs?name=snippet_Second)]

The preceding code:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
ai-usage: ai-assisted
ms.date: 10/15/2026
---

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

The Model-View-Controller (MVC) architectural pattern separates an app into three main components: **M**odel, **V**iew, and **C**ontroller. The MVC pattern helps you create apps that are more testable and easier to update than traditional monolithic apps.
Expand Down Expand Up @@ -46,7 +51,7 @@ Select the **EXPLORER** icon and then control-click (right-click) **Controllers

Replace the contents of `Controllers/HelloWorldController.cs` with the following code:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie80/Controllers/HelloWorldController.cs?name=snippet_First)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie80/Controllers/HelloWorldController.cs?name=snippet_First)]

Every `public` method in a controller is callable as an HTTP endpoint. In the sample above, both methods return a string. Note the comments preceding each method.

Expand Down Expand Up @@ -92,7 +97,7 @@ Modify the code to pass some parameter information from the URL to the controlle

Change the `Welcome` method to include two parameters as shown in the following code.

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie80/Controllers/HelloWorldController.cs?name=snippet_Second)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie80/Controllers/HelloWorldController.cs?name=snippet_Second)]

The preceding code:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
ai-usage: ai-assisted
ms.date: 10/15/2026
---

:::moniker range="= aspnetcore-9.0"

The Model-View-Controller (MVC) architectural pattern separates an app into three main components: **M**odel, **V**iew, and **C**ontroller. The MVC pattern helps you create apps that are more testable and easier to update than traditional monolithic apps.
Expand Down Expand Up @@ -46,7 +51,7 @@ Select the **EXPLORER** icon and then control-click (right-click) **Controllers

Replace the contents of `Controllers/HelloWorldController.cs` with the following code:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie90/Controllers/HelloWorldController.cs?name=snippet_First)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie90/Controllers/HelloWorldController.cs?name=snippet_First)]

Every `public` method in a controller is callable as an HTTP endpoint. In the sample above, both methods return a string. Note the comments preceding each method.

Expand Down Expand Up @@ -92,7 +97,7 @@ Modify the code to pass some parameter information from the URL to the controlle

Change the `Welcome` method to include two parameters as shown in the following code.

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie90/Controllers/HelloWorldController.cs?name=snippet_Second)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie90/Controllers/HelloWorldController.cs?name=snippet_Second)]

The preceding code:

Expand Down
4 changes: 2 additions & 2 deletions aspnetcore/tutorials/first-mvc-app/adding-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Add a file named `Movie.cs` to the *Models* folder.

Update the `Models/Movie.cs` file with the following code:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie10/Models/Movie.cs?name=snippet_First)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie10/Models/Movie.cs?name=snippet_First)]

The `Movie` class contains an `Id` field, which is required by the database for the primary key.

Expand Down Expand Up @@ -391,7 +391,7 @@ This `@model` directive allows access to the movie that the controller passed to

Examine the `Index.cshtml` view and the `Index` method in the Movies controller. Notice how the code creates a `List` object when it calls the `View` method. The code passes this `Movies` list from the `Index` action method to the view:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie10/Controllers/MoviesController.cs?name=snippet_FirstIndexNoSearch)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie10/Controllers/MoviesController.cs?name=snippet_FirstIndexNoSearch)]

The code returns [problem details](xref:fundamentals/error-handling-api#problem-details-service) if the `Movie` property of the data context is null.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
ai-usage: ai-assisted
ms.date: 10/15/2026
---

:::moniker range="= aspnetcore-7.0"

In this tutorial, classes are added for managing movies in a database. These classes are the "**M**odel" part of the **M**VC app.
Expand Down Expand Up @@ -372,11 +377,11 @@ Scaffolding added a connection string to the `appsettings.json` file:

# [Visual Studio](#tab/visual-studio)

[!code-json[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie70/appsettings.json?highlight=9-10)]
[!code-json[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie70/appsettings.json?highlight=9-10)]

# [Visual Studio Code / Visual Studio for Mac](#tab/visual-studio-code+visual-studio-mac)

[!code-json[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie70/appsettings_SQLite.json?highlight=9-10)]
[!code-json[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie70/appsettings_SQLite.json?highlight=9-10)]

---

Expand All @@ -386,7 +391,7 @@ For local development, the [ASP.NET Core configuration system](xref:fundamentals

Examine the `Migrations/{timestamp}_InitialCreate.cs` migration file:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie70/Migrations/20210915202210_InitialCreate.cs)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie70/Migrations/20210915202210_InitialCreate.cs)]

In the preceding code:

Expand All @@ -399,7 +404,7 @@ Open the `Controllers/MoviesController.cs` file and examine the constructor:

<!-- l.. Make copy of Movies controller (or use the old one as I did in the 3.0 upgrade) because we comment out the initial index method and update it later -->

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie70/Controllers/MoviesController.cs?name=snippet_Constructor)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie70/Controllers/MoviesController.cs?name=snippet_Constructor)]

The constructor uses [Dependency Injection](xref:fundamentals/dependency-injection) to inject the database context (`MvcMovieContext`) into the controller. The database context is used in each of the [CRUD](https://wikipedia.org/wiki/Create,_read,_update_and_delete) methods in the controller.

Expand All @@ -417,7 +422,7 @@ MVC provides the ability to pass strongly typed model objects to a view. This st

Examine the generated `Details` method in the `Controllers/MoviesController.cs` file:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie70/Controllers/MoviesController.cs?name=snippet_Details)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie70/Controllers/MoviesController.cs?name=snippet_Details)]

The `id` parameter is generally passed as route data. For example, `https://localhost:5001/movies/details/1` sets:

Expand Down Expand Up @@ -446,7 +451,7 @@ return View(movie);

Examine the contents of the `Views/Movies/Details.cshtml` file:

[!code-cshtml[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie70/Views/Movies/DetailsOriginal.cshtml)]
[!code-cshtml[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie70/Views/Movies/DetailsOriginal.cshtml)]

The `@model` statement at the top of the view file specifies the type of object that the view expects. When the movie controller was created, the following `@model` statement was included:

Expand All @@ -466,11 +471,11 @@ When the movies controller was created, scaffolding included the following `@mod

<!-- Copy Index.cshtml to IndexOriginal.cshtml -->

[!code-cshtml[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie70/Views/Movies/IndexOriginal.cshtml?range=1)]
[!code-cshtml[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie70/Views/Movies/IndexOriginal.cshtml?range=1)]

The `@model` directive allows access to the list of movies that the controller passed to the view by using a `Model` object that's strongly typed. For example, in the `Index.cshtml` view, the code loops through the movies with a `foreach` statement over the strongly typed `Model` object:

[!code-cshtml[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie70/Views/Movies/IndexOriginal.cshtml?highlight=1,31,34,37,40,43,46-48)]
[!code-cshtml[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie70/Views/Movies/IndexOriginal.cshtml?highlight=1,31,34,37,40,43,46-48)]

Because the `Model` object is strongly typed as an `IEnumerable<Movie>` object, each item in the loop is typed as `Movie`. Among other benefits, the compiler validates the types used in the code.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
ai-usage: ai-assisted
ms.date: 10/15/2026
---

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

In this tutorial, classes are added for managing movies in a database. These classes are the "**M**odel" part of the **M**VC app.
Expand All @@ -22,7 +27,7 @@ Add a file named `Movie.cs` to the *Models* folder.

Update the `Models/Movie.cs` file with the following code:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie80/Models/Movie.cs?name=snippet_First)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie80/Models/Movie.cs?name=snippet_First)]

The `Movie` class contains an `Id` field, which is required by the database for the primary key.

Expand Down Expand Up @@ -362,7 +367,7 @@ This `@model` directive allows access to the movie that the controller passed to

Examine the `Index.cshtml` view and the `Index` method in the Movies controller. Notice how the code creates a `List` object when it calls the `View` method. The code passes this `Movies` list from the `Index` action method to the view:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie80/Controllers/MoviesController.cs?name=snippet_FirstIndexNoSearch)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie80/Controllers/MoviesController.cs?name=snippet_FirstIndexNoSearch)]

The code returns [problem details](xref:fundamentals/error-handling-api#problem-details-service) if the `Movie` property of the data context is null.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
ai-usage: ai-assisted
ms.date: 10/15/2026
---

:::moniker range="= aspnetcore-9.0"

In this tutorial, classes are added for managing movies in a database. These classes are the "**M**odel" part of the **M**VC app.
Expand All @@ -22,7 +27,7 @@ Add a file named `Movie.cs` to the *Models* folder.

Update the `Models/Movie.cs` file with the following code:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie90/Models/Movie.cs?name=snippet_First)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie90/Models/Movie.cs?name=snippet_First)]

The `Movie` class contains an `Id` field, which is required by the database for the primary key.

Expand Down Expand Up @@ -375,7 +380,7 @@ This `@model` directive allows access to the movie that the controller passed to

Examine the `Index.cshtml` view and the `Index` method in the Movies controller. Notice how the code creates a `List` object when it calls the `View` method. The code passes this `Movies` list from the `Index` action method to the view:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie90/Controllers/MoviesController.cs?name=snippet_FirstIndexNoSearch)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie90/Controllers/MoviesController.cs?name=snippet_FirstIndexNoSearch)]

The code returns [problem details](xref:fundamentals/error-handling-api#problem-details-service) if the `Movie` property of the data context is null.

Expand Down
6 changes: 3 additions & 3 deletions aspnetcore/tutorials/first-mvc-app/adding-view.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: Part 3, add a view to an ASP.NET Core MVC app
ai-usage: ai-assisted
description: Part 3 of tutorial series on ASP.NET Core MVC.
ms.date: 01/22/2026
monikerRange: '>= aspnetcore-3.1'
ms.date: 01/22/2026
uid: tutorials/first-mvc-app/adding-view
---

Expand Down Expand Up @@ -91,7 +91,7 @@ Find the `@RenderBody()` line. `RenderBody` is a placeholder where all the view-

Replace the content of the `Views/Shared/_Layout.cshtml` file with the following markup. The changes are highlighted:

[!code-cshtml[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie10/Views/Shared/_Layout.cshtml?highlight=6,15,41)]
[!code-cshtml[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie10/Views/Shared/_Layout.cshtml?highlight=6,15,41)]

The preceding markup made the following changes:

Expand Down Expand Up @@ -173,7 +173,7 @@ In `HelloWorldController.cs`, change the `Welcome` method to add a `Message` and

The `ViewData` dictionary is a dynamic object, which means any type can be used. The `ViewData` object has no defined properties until something is added. The [MVC model binding system](xref:mvc/models/model-binding) automatically maps the named parameters `name` and `numTimes` from the query string to parameters in the method. The complete `HelloWorldController`:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie10/Controllers/HelloWorldController.cs?name=snippet_ViewData&highlight=12-17)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie10/Controllers/HelloWorldController.cs?name=snippet_ViewData&highlight=12-17)]

The `ViewData` dictionary object contains data that will be passed to the view.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
---
ai-usage: ai-assisted
ms.date: 10/15/2026
---

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

In this section, you modify the `HelloWorldController` class to use [Razor](xref:mvc/views/razor) view files. This cleanly encapsulates the process of generating HTML responses to a client.
Expand Down Expand Up @@ -78,7 +83,7 @@ Find the `@RenderBody()` line. `RenderBody` is a placeholder where all the view-

Replace the content of the `Views/Shared/_Layout.cshtml` file with the following markup. The changes are highlighted:

[!code-cshtml[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie80/Views/Shared/_Layout.cshtml?highlight=6,14,40)]
[!code-cshtml[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie80/Views/Shared/_Layout.cshtml?highlight=6,14,40)]

The preceding markup made the following changes:

Expand Down Expand Up @@ -162,7 +167,7 @@ In `HelloWorldController.cs`, change the `Welcome` method to add a `Message` and

The `ViewData` dictionary is a dynamic object, which means any type can be used. The `ViewData` object has no defined properties until something is added. The [MVC model binding system](xref:mvc/models/model-binding) automatically maps the named parameters `name` and `numTimes` from the query string to parameters in the method. The complete `HelloWorldController`:

[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/mvcmovie80/Controllers/HelloWorldController.cs?name=snippet_ViewData&highlight=12-17)]
[!code-csharp[](~/tutorials/first-mvc-app/start-mvc/samples/MvcMovie80/Controllers/HelloWorldController.cs?name=snippet_ViewData&highlight=12-17)]

The `ViewData` dictionary object contains data that will be passed to the view.

Expand Down
Loading
Loading