diff --git a/.gitignore b/.gitignore index 08bf0c26bef2..ae07d0fbe872 100644 --- a/.gitignore +++ b/.gitignore @@ -227,3 +227,5 @@ __pycache__/ # Windows thumbnail cache files Thumbs.db +# NuGet +.nuget/ diff --git a/aspnetcore/tutorials/min-web-api.md b/aspnetcore/tutorials/min-web-api.md index 8c0be13400eb..165c09452ab9 100644 --- a/aspnetcore/tutorials/min-web-api.md +++ b/aspnetcore/tutorials/min-web-api.md @@ -2,9 +2,10 @@ title: "Tutorial: Create a minimal API with ASP.NET Core" author: wadepickett description: Learn how to build a minimal API with ASP.NET Core. +ai-usage: ai-assisted ms.author: wpickett -ms.date: 07/29/2024 ms.custom: engagement-fy24 +ms.date: 11/13/2025 monikerRange: '>= aspnetcore-6.0' uid: tutorials/min-web-api --- @@ -33,6 +34,7 @@ This tutorial creates the following API: | `GET /todoitems/{id}` | Get an item by ID | None | To-do item | | `POST /todoitems` | Add a new item | To-do item | To-do item | | `PUT /todoitems/{id}` | Update an existing item   | To-do item | None | +| `PATCH /todoitems/{id}` | Partially update an item  | Partial to-do item | None | | `DELETE /todoitems/{id}`     | Delete an item     | None | None | ## Prerequisites @@ -513,6 +515,73 @@ Use Swagger to send a PUT request: --- +## Examine the PATCH endpoint + +The sample app implements a single PATCH endpoint using `MapPatch`: + +[!code-csharp[](~/tutorials/min-web-api/samples/9.x/todo/Program.cs?name=snippet_patch)] + +This method is similar to the `MapPut` method, except it uses HTTP PATCH and only updates the fields provided in the request. A successful response returns [204 (No Content)](https://www.rfc-editor.org/rfc/rfc9110#status.204). According to the HTTP specification, a PATCH request enables partial updates, allowing clients to send only the fields that need to be changed. + +> [!NOTE] +> PATCH operations allow partial updates to resources. For more advanced partial updates using JSON Patch documents, see . + +## Test the PATCH endpoint + +This sample uses an in-memory database that must be initialized each time the app is started. There must be an item in the database before you make a PATCH call. Call GET to ensure there's an item in the database before making a PATCH call. + +Update only the `name` property of the to-do item that has `Id = 1` and set its name to `"run errands"`. + +# [Visual Studio](#tab/visual-studio) + +* In **Endpoints Explorer**, right-click the **PATCH** endpoint, and select **Generate request**. + + The following content is added to the `TodoApi.http` file: + + ```http + PATCH {{TodoApi_HostAddress}}/todoitems/{id} + + ### + ``` + +* In the PATCH request line, replace `{id}` with `1`. + +* Add the following lines immediately after the PATCH request line: + + ```http + Content-Type: application/json + + { + "name": "run errands" + } + ``` + + The preceding code adds a Content-Type header and a JSON request body with only the field to update. + +* Select the **Send request** link that is above the new PATCH request line. + + The PATCH request is sent to the app and the response is displayed in the **Response** pane. The response body is empty, and the status code is 204. + +# [Visual Studio Code](#tab/visual-studio-code) + +Use Swagger to send a PATCH request: + +* Select **Patch /todoitems/{id}** > **Try it out**. + +* Set the **id** field to `1`. + +* Set the request body to the following JSON: + + ```json + { + "name": "run errands" + } + ``` + +* Select **Execute**. + +--- + ## Examine and test the DELETE endpoint The sample app implements a single DELETE endpoint using `MapDelete`: diff --git a/aspnetcore/tutorials/min-web-api/includes/min-web-api6-7.md b/aspnetcore/tutorials/min-web-api/includes/min-web-api6-7.md index 59947234812b..6290b6beecb1 100644 --- a/aspnetcore/tutorials/min-web-api/includes/min-web-api6-7.md +++ b/aspnetcore/tutorials/min-web-api/includes/min-web-api6-7.md @@ -15,6 +15,7 @@ This tutorial creates the following API: | `GET /todoitems/{id}` | Get an item by ID | None | To-do item | | `POST /todoitems` | Add a new item | To-do item | To-do item | | `PUT /todoitems/{id}` | Update an existing item   | To-do item | None | +| `PATCH /todoitems/{id}` | Partially update an item  | Partial to-do item | None | | `DELETE /todoitems/{id}`     | Delete an item     | None | None | ## Prerequisites @@ -320,6 +321,39 @@ Use Swagger to send a PUT request: * Select **Execute**. +## Examine the PATCH endpoint + +The sample app implements a single PATCH endpoint using `MapPatch`: + +[!code-csharp[](~/tutorials/min-web-api/samples/7.x/todo/Program.cs?name=snippet_patch)] + +This method is similar to the `MapPut` method, except it uses HTTP PATCH and only updates the fields provided in the request. A successful response returns [204 (No Content)](https://www.rfc-editor.org/rfc/rfc9110#status.204). According to the HTTP specification, a PATCH request enables partial updates, allowing clients to send only the fields that need to be changed. + +> [!NOTE] +> PATCH operations allow partial updates to resources. For more advanced partial updates using JSON Patch documents, see . + +## Test the PATCH endpoint + +This sample uses an in-memory database that must be initialized each time the app is started. There must be an item in the database before you make a PATCH call. Call GET to ensure there's an item in the database before making a PATCH call. + +Update only the `name` property of the to-do item that has `Id = 1` and set its name to `"run errands"`. + +Use Swagger to send a PATCH request: + +* Select **Patch /todoitems/{id}** > **Try it out**. + +* Set the **id** field to `1`. + +* Set the request body to the following JSON: + + ```json + { + "name": "run errands" + } + ``` + +* Select **Execute**. + ## Examine and test the DELETE endpoint The sample app implements a single DELETE endpoint using `MapDelete`: diff --git a/aspnetcore/tutorials/min-web-api/includes/min-web-api8.md b/aspnetcore/tutorials/min-web-api/includes/min-web-api8.md index c3e3d2a2b371..3ea48fab312d 100644 --- a/aspnetcore/tutorials/min-web-api/includes/min-web-api8.md +++ b/aspnetcore/tutorials/min-web-api/includes/min-web-api8.md @@ -15,6 +15,7 @@ This tutorial creates the following API: | `GET /todoitems/{id}` | Get an item by ID | None | To-do item | | `POST /todoitems` | Add a new item | To-do item | To-do item | | `PUT /todoitems/{id}` | Update an existing item   | To-do item | None | +| `PATCH /todoitems/{id}` | Partially update an item  | Partial to-do item | None | | `DELETE /todoitems/{id}`     | Delete an item     | None | None | ## Prerequisites @@ -491,6 +492,73 @@ Use Swagger to send a PUT request: --- +## Examine the PATCH endpoint + +The sample app implements a single PATCH endpoint using `MapPatch`: + +[!code-csharp[](~/tutorials/min-web-api/samples/8.x/todo/Program.cs?name=snippet_patch)] + +This method is similar to the `MapPut` method, except it uses HTTP PATCH and only updates the fields provided in the request. A successful response returns [204 (No Content)](https://www.rfc-editor.org/rfc/rfc9110#status.204). According to the HTTP specification, a PATCH request enables partial updates, allowing clients to send only the fields that need to be changed. + +> [!NOTE] +> PATCH operations allow partial updates to resources. For more advanced partial updates using JSON Patch documents, see . + +## Test the PATCH endpoint + +This sample uses an in-memory database that must be initialized each time the app is started. There must be an item in the database before you make a PATCH call. Call GET to ensure there's an item in the database before making a PATCH call. + +Update only the `name` property of the to-do item that has `Id = 1` and set its name to `"run errands"`. + +# [Visual Studio](#tab/visual-studio) + +* In **Endpoints Explorer**, right-click the **PATCH** endpoint, and select **Generate request**. + + The following content is added to the `TodoApi.http` file: + + ``` + PATCH {{TodoApi_HostAddress}}/todoitems/{id} + + ### + ``` + +* In the PATCH request line, replace `{id}` with `1`. + +* Add the following lines immediately after the PATCH request line: + + ``` + Content-Type: application/json + + { + "name": "run errands" + } + ``` + + The preceding code adds a Content-Type header and a JSON request body with only the field to update. + +* Select the **Send request** link that is above the new PATCH request line. + + The PATCH request is sent to the app and the response is displayed in the **Response** pane. The response body is empty, and the status code is 204. + +# [Visual Studio Code](#tab/visual-studio-code) + +Use Swagger to send a PATCH request: + +* Select **Patch /todoitems/{id}** > **Try it out**. + +* Set the **id** field to `1`. + +* Set the request body to the following JSON: + + ```json + { + "name": "run errands" + } + ``` + +* Select **Execute**. + +--- + ## Examine and test the DELETE endpoint The sample app implements a single DELETE endpoint using `MapDelete`: diff --git a/aspnetcore/tutorials/min-web-api/samples/7.x/todo/Program.cs b/aspnetcore/tutorials/min-web-api/samples/7.x/todo/Program.cs index 54881cf93541..49872a36175c 100644 --- a/aspnetcore/tutorials/min-web-api/samples/7.x/todo/Program.cs +++ b/aspnetcore/tutorials/min-web-api/samples/7.x/todo/Program.cs @@ -61,6 +61,22 @@ is Todo todo }); // +// +app.MapPatch("/todoitems/{id}", async (int id, Todo inputTodo, TodoDb db) => +{ + var todo = await db.Todos.FindAsync(id); + + if (todo is null) return Results.NotFound(); + + if (inputTodo.Name is not null) todo.Name = inputTodo.Name; + if (inputTodo.IsComplete != todo.IsComplete) todo.IsComplete = inputTodo.IsComplete; + + await db.SaveChangesAsync(); + + return Results.NoContent(); +}); +// + // app.MapDelete("/todoitems/{id}", async (int id, TodoDb db) => { diff --git a/aspnetcore/tutorials/min-web-api/samples/8.x/todo/Program.cs b/aspnetcore/tutorials/min-web-api/samples/8.x/todo/Program.cs index 54881cf93541..49872a36175c 100644 --- a/aspnetcore/tutorials/min-web-api/samples/8.x/todo/Program.cs +++ b/aspnetcore/tutorials/min-web-api/samples/8.x/todo/Program.cs @@ -61,6 +61,22 @@ is Todo todo }); // +// +app.MapPatch("/todoitems/{id}", async (int id, Todo inputTodo, TodoDb db) => +{ + var todo = await db.Todos.FindAsync(id); + + if (todo is null) return Results.NotFound(); + + if (inputTodo.Name is not null) todo.Name = inputTodo.Name; + if (inputTodo.IsComplete != todo.IsComplete) todo.IsComplete = inputTodo.IsComplete; + + await db.SaveChangesAsync(); + + return Results.NoContent(); +}); +// + // app.MapDelete("/todoitems/{id}", async (int id, TodoDb db) => { diff --git a/aspnetcore/tutorials/min-web-api/samples/9.x/todo/Program.cs b/aspnetcore/tutorials/min-web-api/samples/9.x/todo/Program.cs index 54881cf93541..49872a36175c 100644 --- a/aspnetcore/tutorials/min-web-api/samples/9.x/todo/Program.cs +++ b/aspnetcore/tutorials/min-web-api/samples/9.x/todo/Program.cs @@ -61,6 +61,22 @@ is Todo todo }); // +// +app.MapPatch("/todoitems/{id}", async (int id, Todo inputTodo, TodoDb db) => +{ + var todo = await db.Todos.FindAsync(id); + + if (todo is null) return Results.NotFound(); + + if (inputTodo.Name is not null) todo.Name = inputTodo.Name; + if (inputTodo.IsComplete != todo.IsComplete) todo.IsComplete = inputTodo.IsComplete; + + await db.SaveChangesAsync(); + + return Results.NoContent(); +}); +// + // app.MapDelete("/todoitems/{id}", async (int id, TodoDb db) => {