diff --git a/aspnetcore/includes/net-prereqs-vs-10-latest.md b/aspnetcore/includes/net-prereqs-vs-10-latest.md index 11c7bf836918..5a5baf551b54 100644 --- a/aspnetcore/includes/net-prereqs-vs-10-latest.md +++ b/aspnetcore/includes/net-prereqs-vs-10-latest.md @@ -1,3 +1,3 @@ * [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/) with the **ASP.NET and web development** workload. - ![VS22 installer workloads](~/tutorials/min-web-api/_static/asp-net-web-dev.png) + ![VS22 installer workloads](~/tutorials/min-web-api/static/asp-net-web-dev.png) diff --git a/aspnetcore/includes/net-prereqs-vs-10.md b/aspnetcore/includes/net-prereqs-vs-10.md index 8692435eb86f..2c64716648ec 100644 --- a/aspnetcore/includes/net-prereqs-vs-10.md +++ b/aspnetcore/includes/net-prereqs-vs-10.md @@ -1,3 +1,3 @@ * [The latest version of Visual Studio](https://visualstudio.microsoft.com/downloads/) with the **ASP.NET and web development** workload. - :::image type="content" source="~/tutorials/min-web-api/_static/asp-net-web-dev-2026.png" alt-text="VS26 installer workloads" lightbox="~/tutorials/min-web-api/_static/asp-net-web-dev-2026.png"::: + :::image type="content" source="~/tutorials/min-web-api/static/asp-net-web-dev-2026.png" alt-text="VS26 installer workloads" lightbox="~/tutorials/min-web-api/static/asp-net-web-dev-2026.png"::: diff --git a/aspnetcore/includes/net-prereqs-vs-11-latest.md b/aspnetcore/includes/net-prereqs-vs-11-latest.md index 2b192ebd3b24..aa0f36e2a496 100644 --- a/aspnetcore/includes/net-prereqs-vs-11-latest.md +++ b/aspnetcore/includes/net-prereqs-vs-11-latest.md @@ -1,3 +1,3 @@ * [Visual Studio](https://visualstudio.microsoft.com/downloads/) with the **ASP.NET and web development** workload. - ![VS22 installer workloads](~/tutorials/min-web-api/_static/asp-net-web-dev.png) + ![VS22 installer workloads](~/tutorials/min-web-api/static/asp-net-web-dev.png) diff --git a/aspnetcore/includes/net-prereqs-vs-7.0.md b/aspnetcore/includes/net-prereqs-vs-7.0.md index 52133b7146ad..6fdbb1ce77ba 100644 --- a/aspnetcore/includes/net-prereqs-vs-7.0.md +++ b/aspnetcore/includes/net-prereqs-vs-7.0.md @@ -1,4 +1,4 @@ * [Visual Studio 2022](https://visualstudio.microsoft.com/vs/#download) with the **ASP.NET and web development** workload. - ![VS22 installer workloads](~/tutorials/min-web-api/_static/asp-net-web-dev.png) + ![VS22 installer workloads](~/tutorials/min-web-api/static/asp-net-web-dev.png) diff --git a/aspnetcore/includes/net-prereqs-vs-8.0.md b/aspnetcore/includes/net-prereqs-vs-8.0.md index 290eb943c17e..fad51f7bacc5 100644 --- a/aspnetcore/includes/net-prereqs-vs-8.0.md +++ b/aspnetcore/includes/net-prereqs-vs-8.0.md @@ -1,4 +1,4 @@ * [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/) with the **ASP.NET and web development** workload. - ![VS22 installer workloads](~/tutorials/min-web-api/_static/asp-net-web-dev.png) + ![VS22 installer workloads](~/tutorials/min-web-api/static/asp-net-web-dev.png) diff --git a/aspnetcore/includes/net-prereqs-vs-9.0.md b/aspnetcore/includes/net-prereqs-vs-9.0.md index bd5e4160d33e..a7265f8617ed 100644 --- a/aspnetcore/includes/net-prereqs-vs-9.0.md +++ b/aspnetcore/includes/net-prereqs-vs-9.0.md @@ -1,4 +1,4 @@ * [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/) with the **ASP.NET and web development** workload. - ![VS22 installer workloads](~/tutorials/min-web-api/_static/asp-net-web-dev.png) + ![VS22 installer workloads](~/tutorials/min-web-api/static/asp-net-web-dev.png) diff --git a/aspnetcore/includes/net-prereqs-vs-latest.md b/aspnetcore/includes/net-prereqs-vs-latest.md index 11c7bf836918..5a5baf551b54 100644 --- a/aspnetcore/includes/net-prereqs-vs-latest.md +++ b/aspnetcore/includes/net-prereqs-vs-latest.md @@ -1,3 +1,3 @@ * [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/) with the **ASP.NET and web development** workload. - ![VS22 installer workloads](~/tutorials/min-web-api/_static/asp-net-web-dev.png) + ![VS22 installer workloads](~/tutorials/min-web-api/static/asp-net-web-dev.png) diff --git a/aspnetcore/tutorials/min-web-api.md b/aspnetcore/tutorials/min-web-api.md index 6991bcb3a982..1152b039d6f7 100644 --- a/aspnetcore/tutorials/min-web-api.md +++ b/aspnetcore/tutorials/min-web-api.md @@ -4,8 +4,7 @@ author: wadepickett description: Learn how to build a minimal API with ASP.NET Core. ai-usage: ai-assisted ms.author: wpickett -ms.custom: engagement-fy24 -ms.date: 02/12/2026 +ms.date: 06/03/2026 monikerRange: '>= aspnetcore-6.0' uid: tutorials/min-web-api --- @@ -15,9 +14,9 @@ uid: tutorials/min-web-api [!INCLUDE[](~/includes/not-latest-version.md)] -By [Rick Anderson](https://twitter.com/RickAndMSFT) and [Tom Dykstra](https://github.com/tdykstra) +By [Wade Pickett](https://github.com/wadepickett) and [Tom Dykstra](https://github.com/tdykstra) -:::moniker range=">= aspnetcore-9.0" +:::moniker range=">= aspnetcore-10.0" Minimal APIs are architected to create HTTP APIs with minimal dependencies. They're ideal for microservices and apps that want to include only the minimum files, features, and dependencies in ASP.NET Core. @@ -41,11 +40,11 @@ This tutorial creates the following API: # [Visual Studio](#tab/visual-studio) -[!INCLUDE[](~/includes/net-prereqs-vs-9.0.md)] +[!INCLUDE[](~/includes/net-prereqs-vs-10.md)] # [Visual Studio Code](#tab/visual-studio-code) -[!INCLUDE[](~/includes/net-prereqs-vsc-9.0.md)] +[!INCLUDE[](~/includes/net-prereqs-vsc-10.0.md)] --- @@ -53,20 +52,20 @@ This tutorial creates the following API: # [Visual Studio](#tab/visual-studio) -* Start Visual Studio 2022 and select **Create a new project**. +* Start Visual Studio 2026 and select **Create a new project**. * In the **Create a new project** dialog: * Enter `Empty` in the **Search for templates** search box. * Select the **ASP.NET Core Empty** template and select **Next**. - ![Visual Studio Create a new project](~/tutorials/min-web-api/_static/9.x/create-new-project-empty-vs17.11.0.png) + ![Visual Studio Create a new project](~/tutorials/min-web-api/static/10/create-new-project-empty-vs18-6-2.png) * Name the project *TodoApi* and select **Next**. * In the **Additional information** dialog: - * Select **.NET 9.0** + * Select **.NET 10.0 (Long Term Support)** * Uncheck **Do not use top-level statements** * Select **Create** - ![Additional information](~/tutorials/min-web-api/_static/9.x/add-info-vs17.11.0.png) + ![Additional information](~/tutorials/min-web-api/static/10/add-info-vs18-6-2.png) # [Visual Studio Code](#tab/visual-studio-code) @@ -136,7 +135,6 @@ NuGet packages must be added to support the database and diagnostics used in thi * From the **Tools** menu, select **NuGet Package Manager > Manage NuGet Packages for Solution**. * Select the **Browse** tab. -* Select **Include Prelease**. * Enter **Microsoft.EntityFrameworkCore.InMemory** in the search box, and then select `Microsoft.EntityFrameworkCore.InMemory`. * Select the **Project** checkbox in the right pane and then select **Install**. * Follow the preceding instructions to add the `Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore` package. @@ -184,7 +182,7 @@ This tutorial uses [Endpoints Explorer and .http files](xref:test/http-files#use # [Visual Studio Code](#tab/visual-studio-code) -## Create API testing UI with Swagger +## Test the web API There are many available web API testing tools to choose from, and you can follow this tutorial's introductory API test steps with your own preferred tool. @@ -205,6 +203,7 @@ For more information on using OpenAPI and NSwag with ASP.NET, see **Other Windows** > **Endpoints Explorer**. * Right-click the **POST** endpoint and select **Generate request**. - ![Endpoints Explorer context menu highlighting Generate Request menu item.](~/tutorials/min-web-api/_static/9.x/generate-request-vs17.8.0.png) + ![Endpoints Explorer context menu highlighting Generate Request menu item.](~/tutorials/min-web-api/static/9.x/generate-request-vs17.8.0.png) A new file is created in the project folder named `TodoApi.http`, with contents similar to the following example: @@ -289,17 +288,17 @@ The POST endpoint will be used to add data to the app. * Select the **Send request** link that is above the `POST` request line. - ![.http file window with run link highlighted.](~/tutorials/min-web-api/_static/9.x/http-file-run-button-vs17.8.0.png) + ![.http file window with run link highlighted.](~/tutorials/min-web-api/static/9.x/http-file-run-button-vs17.8.0.png) The POST request is sent to the app and the response is displayed in the **Response** pane. - ![.http file window with response from the POST request.](~/tutorials/min-web-api/_static/9.x/http-file-window-with-response-vs17.8.0.png) + ![.http file window with response from the POST request.](~/tutorials/min-web-api/static/9.x/http-file-window-with-response-vs17.8.0.png) # [Visual Studio Code](#tab/visual-studio-code) * With the app still running, in the browser, navigate to `https://localhost:/swagger` to display the API testing page generated by Swagger. - ![Swagger generated API testing page](~/tutorials/min-web-api/_static/9.x/swagger.png) + ![Swagger generated API testing page](~/tutorials/min-web-api/static/9.x/swagger.png) * On the Swagger API testing page, select **Post /todoitems** > **Try it out**. * Note that the **Request body** field contains a generated example format reflecting the parameters for the API. @@ -314,11 +313,11 @@ The POST endpoint will be used to add data to the app. * Select **Execute**. - ![Swagger with Post request](~/tutorials/min-web-api/_static/9.x/swagger-post-1.png) + ![Swagger with Post request](~/tutorials/min-web-api/static/9.x/swagger-post-1.png) Swagger provides a **Responses** pane below the **Execute** button. - ![Swagger with Post resonse](~/tutorials/min-web-api/_static/9.x/swagger-post-responses.png) + ![Swagger with Post response](~/tutorials/min-web-api/static/9.x/swagger-post-responses.png) Note a few of the useful details: @@ -753,5 +752,6 @@ See :::moniker-end -[!INCLUDE[](~/tutorials/min-web-api/includes/min-web-api6-7.md)] -[!INCLUDE[](~/tutorials/min-web-api/includes/min-web-api8.md)] +[!INCLUDE[](~/tutorials/min-web-api/includes/min-web-api-6-7.md)] +[!INCLUDE[](~/tutorials/min-web-api/includes/min-web-api-8.md)] +[!INCLUDE[](~/tutorials/min-web-api/includes/min-web-api-9.md)] diff --git a/aspnetcore/tutorials/min-web-api/includes/min-web-api6-7.md b/aspnetcore/tutorials/min-web-api/includes/min-web-api-6-7.md similarity index 98% rename from aspnetcore/tutorials/min-web-api/includes/min-web-api6-7.md rename to aspnetcore/tutorials/min-web-api/includes/min-web-api-6-7.md index e6a5fd95fcea..738874041e8f 100644 --- a/aspnetcore/tutorials/min-web-api/includes/min-web-api6-7.md +++ b/aspnetcore/tutorials/min-web-api/includes/min-web-api-6-7.md @@ -39,7 +39,7 @@ This tutorial creates the following API: * Enter `Empty` in the **Search for templates** search box. * Select the **ASP.NET Core Empty** template and select **Next**. - ![Visual Studio Create a new project](~/tutorials/min-web-api/_static/empty.png) + ![Visual Studio Create a new project](~/tutorials/min-web-api/static/empty.png) * Name the project *TodoApi* and select **Next**. * In the **Additional information** dialog: @@ -47,7 +47,7 @@ This tutorial creates the following API: * Uncheck **Do not use top-level statements** * Select **Create** - ![Additional information](~/tutorials/min-web-api/_static/add-info7.png) + ![Additional information](~/tutorials/min-web-api/static/add-info7.png) # [Visual Studio Code](#tab/visual-studio-code) @@ -202,7 +202,7 @@ The POST endpoint will be used to add data to the app. * With the app still running, in the browser, navigate to `https://localhost:/swagger` to display the API testing page generated by Swagger. - ![Swagger generated API testing page](~/tutorials/min-web-api/_static/8.x/swagger.png) + ![Swagger generated API testing page](~/tutorials/min-web-api/static/8.x/swagger.png) * On the Swagger API testing page, select **Post /todoitems** > **Try it out**. * Note that the **Request body** field contains a generated example format reflecting the parameters for the API. @@ -217,11 +217,11 @@ The POST endpoint will be used to add data to the app. * Select **Execute**. - ![Swagger with Post](~/tutorials/min-web-api/_static/8.x/swagger-post-1.png) + ![Swagger with Post](~/tutorials/min-web-api/static/8.x/swagger-post-1.png) Swagger provides a **Responses** pane below the **Execute** button. - ![Swagger with Post response](~/tutorials/min-web-api/_static/8.x/swagger-post-responses.png) + ![Swagger with Post response](~/tutorials/min-web-api/static/8.x/swagger-post-responses.png) Note a few of the useful details: @@ -535,7 +535,7 @@ This tutorial creates the following API: * Enter `Empty` in the **Search for templates** search box. * Select the **ASP.NET Core Empty** template and select **Next**. - ![Visual Studio Create a new project](~/tutorials/min-web-api/_static/empty.png) + ![Visual Studio Create a new project](~/tutorials/min-web-api/static/empty.png) * Name the project *TodoApi* and select **Next**. * In the **Additional information** dialog: @@ -700,7 +700,7 @@ The POST endpoint will be used to add data to the app. * With the app still running, in the browser, navigate to `https://localhost:/swagger` to display the API testing page generated by Swagger. - ![Swagger generated API testing page](~/tutorials/min-web-api/_static/8.x/swagger.png) + ![Swagger generated API testing page](~/tutorials/min-web-api/static/8.x/swagger.png) * On the Swagger API testing page, select **Post /todoitems** > **Try it out**. * Note that the **Request body** field contains a generated example format reflecting the parameters for the API. @@ -715,11 +715,11 @@ The POST endpoint will be used to add data to the app. * Select **Execute**. - ![Swagger with Post data](~/tutorials/min-web-api/_static/8.x/swagger-post-1.png) + ![Swagger with Post data](~/tutorials/min-web-api/static/8.x/swagger-post-1.png) Swagger provides a **Responses** pane below the **Execute** button. - ![Swagger with Post resonse pane](~/tutorials/min-web-api/_static/8.x/swagger-post-responses.png) + ![Swagger with Post resonse pane](~/tutorials/min-web-api/static/8.x/swagger-post-responses.png) Note a few of the useful details: diff --git a/aspnetcore/tutorials/min-web-api/includes/min-web-api8.md b/aspnetcore/tutorials/min-web-api/includes/min-web-api-8.md similarity index 98% rename from aspnetcore/tutorials/min-web-api/includes/min-web-api8.md rename to aspnetcore/tutorials/min-web-api/includes/min-web-api-8.md index fbf2ba1217c4..20bc2f373cf8 100644 --- a/aspnetcore/tutorials/min-web-api/includes/min-web-api8.md +++ b/aspnetcore/tutorials/min-web-api/includes/min-web-api-8.md @@ -39,7 +39,7 @@ This tutorial creates the following API: * Enter `Empty` in the **Search for templates** search box. * Select the **ASP.NET Core Empty** template and select **Next**. - ![Visual Studio Create a new project](~/tutorials/min-web-api/_static/8.x/create-new-project-empty-vs17.8.0.png) + ![Visual Studio Create a new project](~/tutorials/min-web-api/static/8.x/create-new-project-empty-vs17.8.0.png) * Name the project *TodoApi* and select **Next**. * In the **Additional information** dialog: @@ -47,7 +47,7 @@ This tutorial creates the following API: * Uncheck **Do not use top-level statements** * Select **Create** - ![Additional information](~/tutorials/min-web-api/_static/8.x/add-info-vs17.9.0.png) + ![Additional information](~/tutorials/min-web-api/static/8.x/add-info-vs17.9.0.png) # [Visual Studio Code](#tab/visual-studio-code) @@ -222,7 +222,7 @@ The POST endpoint will be used to add data to the app. * Select **View** > **Other Windows** > **Endpoints Explorer**. * Right-click the **POST** endpoint and select **Generate request**. - ![Endpoints Explorer context menu highlighting Generate Request menu item.](~/tutorials/min-web-api/_static/8.x/generate-request-vs17.8.0.png) + ![Endpoints Explorer context menu highlighting Generate Request menu item.](~/tutorials/min-web-api/static/8.x/generate-request-vs17.8.0.png) A new file is created in the project folder named `TodoApi.http`, with contents similar to the following example: @@ -269,17 +269,17 @@ The POST endpoint will be used to add data to the app. * Select the **Send request** link that is above the `POST` request line. - ![.http file window with run link highlighted.](~/tutorials/min-web-api/_static/8.x/http-file-run-button-vs17.8.0.png) + ![.http file window with run link highlighted.](~/tutorials/min-web-api/static/8.x/http-file-run-button-vs17.8.0.png) The POST request is sent to the app and the response is displayed in the **Response** pane. - ![.http file window with response from the POST request.](~/tutorials/min-web-api/_static/8.x/http-file-window-with-response-vs17.8.0.png) + ![.http file window with response from the POST request.](~/tutorials/min-web-api/static/8.x/http-file-window-with-response-vs17.8.0.png) # [Visual Studio Code](#tab/visual-studio-code) * With the app still running, in the browser, navigate to `https://localhost:/swagger` to display the API testing page generated by Swagger. - ![Swagger generated API testing page](~/tutorials/min-web-api/_static/8.x/swagger.png) + ![Swagger generated API testing page](~/tutorials/min-web-api/static/8.x/swagger.png) * On the Swagger API testing page, select **Post /todoitems** > **Try it out**. * Note that the **Request body** field contains a generated example format reflecting the parameters for the API. @@ -294,11 +294,11 @@ The POST endpoint will be used to add data to the app. * Select **Execute**. - ![Swagger with Post request](~/tutorials/min-web-api/_static/8.x/swagger-post-1.png) + ![Swagger with Post request](~/tutorials/min-web-api/static/8.x/swagger-post-1.png) Swagger provides a **Responses** pane below the **Execute** button. - ![Swagger with Post resonse](~/tutorials/min-web-api/_static/8.x/swagger-post-responses.png) + ![Swagger with Post resonse](~/tutorials/min-web-api/static/8.x/swagger-post-responses.png) Note a few of the useful details: diff --git a/aspnetcore/tutorials/min-web-api/includes/min-web-api-9.md b/aspnetcore/tutorials/min-web-api/includes/min-web-api-9.md new file mode 100644 index 000000000000..86486f896650 --- /dev/null +++ b/aspnetcore/tutorials/min-web-api/includes/min-web-api-9.md @@ -0,0 +1,734 @@ +:::moniker range="= aspnetcore-9.0" + +Minimal APIs are architected to create HTTP APIs with minimal dependencies. They're ideal for microservices and apps that want to include only the minimum files, features, and dependencies in ASP.NET Core. + +This tutorial teaches the basics of building a Minimal API with ASP.NET Core. Another approach to creating APIs in ASP.NET Core is to use controllers. For help with choosing between Minimal APIs and controller-based APIs, see . For a tutorial on creating an API project based on [controllers](xref:web-api/index) that contains more features, see [Create a web API](xref:tutorials/first-web-api). + +## Overview + +This tutorial creates the following API: + +| API | Description | Request body | Response body | +|----------------------------------------|--------------------------------|--------------|----------------------| +| `GET /todoitems` | Get all to-do items | None | Array of to-do items | +| `GET /todoitems/complete` | Get completed to-do items | None | Array of to-do items | +| `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 + +# [Visual Studio](#tab/visual-studio) + +[!INCLUDE[](~/includes/net-prereqs-vs-9.0.md)] + +# [Visual Studio Code](#tab/visual-studio-code) + +[!INCLUDE[](~/includes/net-prereqs-vsc-9.0.md)] + +--- + +## Create an API project + +# [Visual Studio](#tab/visual-studio) + +* Start Visual Studio 2022 and select **Create a new project**. +* In the **Create a new project** dialog: + * Enter `Empty` in the **Search for templates** search box. + * Select the **ASP.NET Core Empty** template and select **Next**. + + ![Visual Studio Create a new project](~/tutorials/min-web-api/static/9.x/create-new-project-empty-vs17.11.0.png) + +* Name the project *TodoApi* and select **Next**. +* In the **Additional information** dialog: + * Select **.NET 9.0** + * Uncheck **Do not use top-level statements** + * Select **Create** + + ![Additional information](~/tutorials/min-web-api/static/9.x/add-info-vs17.11.0.png) + +# [Visual Studio Code](#tab/visual-studio-code) + +* Open the [integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal). +* Change directories (`cd`) to the folder that will contain the project folder. +* Run the following commands: + + ```dotnetcli + dotnet new web -o TodoApi + cd TodoApi + code -r ../TodoApi + ``` + +* When a dialog box asks if you want to trust the authors, select **Yes**. +* When a dialog box asks if you want to add required assets to the project, select **Yes**. + + The preceding commands create a new web Minimal API project and open it in Visual Studio Code. + +--- + +### Examine the code + +The `Program.cs` file contains the following code: + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todo/Program.cs" id="snippet_min"::: + +The preceding code: + +* Creates a and a with preconfigured defaults. +* Creates an HTTP GET endpoint `/` that returns `Hello World!`. + +### Run the app + +# [Visual Studio](#tab/visual-studio) + + +Press Ctrl+F5 to run without the debugger. + +[!INCLUDE[](~/includes/trustCertVS22.md)] + +Visual Studio launches the [Kestrel web server](xref:fundamentals/servers/kestrel) and opens a browser window. + +`Hello World!` is displayed in the browser. The `Program.cs` file contains a minimal but complete app. + +Close the browser window. + +# [Visual Studio Code](#tab/visual-studio-code) + +[!INCLUDE[](~/includes/trustCertVSC.md)] + +In Visual Studio Code, press Ctrl+F5 (Windows) or control+F5 (macOS) to run the app without debugging. + +The default browser launches with the following URL: `https://localhost:{PORT}` where `{PORT}` is the randomly generated port number. + +Close the browser window. + +In Visual Studio Code, from the *Run* menu, select *Stop Debugging* or press Shift+F5 to stop the app. + +--- + +## Add NuGet packages + +NuGet packages must be added to support the database and diagnostics used in this tutorial. + +# [Visual Studio](#tab/visual-studio) + +* From the **Tools** menu, select **NuGet Package Manager > Manage NuGet Packages for Solution**. +* Select the **Browse** tab. +* Select **Include prerelease**. +* Enter **Microsoft.EntityFrameworkCore.InMemory** in the search box, and then select `Microsoft.EntityFrameworkCore.InMemory`. +* Select the **Project** checkbox in the right pane and then select **Install**. +* Follow the preceding instructions to add the `Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore` package. + +# [Visual Studio Code](#tab/visual-studio-code) + +* Run the following commands: + + ```dotnetcli + dotnet add package Microsoft.EntityFrameworkCore.InMemory + dotnet add package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore + ``` + +--- + +## The model and database context classes + +* In the project folder, create a file named `Todo.cs` with the following code: + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoGroup/Todo.cs"::: + +The preceding code creates the model for this app. A *model* is a class that represents data that the app manages. + +* Create a file named `TodoDb.cs` with the following code: + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoGroup/TodoDb.cs"::: + +The preceding code defines the *database context*, which is the main class that coordinates [Entity Framework](/ef/core/) functionality for a data model. This class derives from the class. + +## Add the API code + +* Replace the contents of the `Program.cs` file with the following code: + +[!code-csharp[](~/tutorials/min-web-api/samples/9.x/todo/Program.cs?name=snippet_all)] + +The following highlighted code adds the database context to the [dependency injection (DI)](xref:fundamentals/dependency-injection) container and enables displaying database-related exceptions: + +[!code-csharp[](~/tutorials/min-web-api/samples/9.x/todo/Program.cs?name=snippet_DI&highlight=2-3)] + +The DI container provides access to the database context and other services. + +# [Visual Studio](#tab/visual-studio) + +This tutorial uses [Endpoints Explorer and .http files](xref:test/http-files#use-endpoints-explorer) to test the API. + +# [Visual Studio Code](#tab/visual-studio-code) + +## Create API testing UI with Swagger + +There are many available web API testing tools to choose from, and you can follow this tutorial's introductory API test steps with your own preferred tool. + +This tutorial utilizes the .NET package [NSwag.AspNetCore](https://www.nuget.org/packages/NSwag.AspNetCore/), which integrates Swagger tools for generating a testing UI adhering to the OpenAPI specification: + +* NSwag: A .NET library that integrates Swagger directly into ASP.NET Core applications, providing middleware and configuration. +* Swagger: A set of open-source tools such as OpenAPIGenerator and SwaggerUI that generate API testing pages that follow the OpenAPI specification. +* OpenAPI specification: A document that describes the capabilities of the API, based on the XML and attribute annotations within the controllers and models. + +For more information on using OpenAPI and NSwag with ASP.NET, see . + +### Install Swagger tooling + +* Run the following command: + + ```dotnetcli + dotnet add package NSwag.AspNetCore + ``` + +The previous command adds the [NSwag.AspNetCore](https://www.nuget.org/packages/NSwag.AspNetCore/) package, which contains tools to generate Swagger documents and UI. + +### Configure Swagger middleware + +* In Program.cs add the following highlighted code before `app` is defined in line `var app = builder.Build();` + + [!code-csharp[](~/tutorials/min-web-api/samples/9.x/todo_SwaggerVersion/Program.cs?name=snippet_swagger_add_service&highlight=7-13)] + +In the previous code: + + * `builder.Services.AddEndpointsApiExplorer();`: Enables the API Explorer, which is a service that provides metadata about the HTTP API. The API Explorer is used by Swagger to generate the Swagger document. + * `builder.Services.AddOpenApiDocument(config => {...});`: Adds the Swagger OpenAPI document generator to the application services and configures it to provide more information about the API, such as its title and version. For information on providing more robust API details, see + +* Add the following highlighted code to the next line after `app` is defined in line `var app = builder.Build();` + + [!code-csharp[](~/tutorials/min-web-api/samples/9.x/todo_SwaggerVersion/Program.cs?name=snippet_swagger_enable_middleware&highlight=2-12)] + + The previous code enables the Swagger middleware for serving the generated JSON document and the Swagger UI. Swagger is only enabled in a development environment. Enabling Swagger in a production environment could expose potentially sensitive details about the API's structure and implementation. + + + +--- + +## Test posting data + +The following code in `Program.cs` creates an HTTP POST endpoint `/todoitems` that adds data to the in-memory database: + +[!code-csharp[](~/tutorials/min-web-api/samples/9.x/todo/Program.cs?name=snippet_post)] + +Run the app. The browser displays a 404 error because there's no longer a `/` endpoint. + +The POST endpoint will be used to add data to the app. + +# [Visual Studio](#tab/visual-studio) + +* Select **View** > **Other Windows** > **Endpoints Explorer**. +* Right-click the **POST** endpoint and select **Generate request**. + + ![Endpoints Explorer context menu highlighting Generate Request menu item.](~/tutorials/min-web-api/static/9.x/generate-request-vs17.8.0.png) + + A new file is created in the project folder named `TodoApi.http`, with contents similar to the following example: + + ```http + @TodoApi_HostAddress = https://localhost:7031 + + POST {{TodoApi_HostAddress}}/todoitems + + ### + ``` + + * The first line creates a variable that is used for all of the endpoints. + * The next line defines a POST request. + * The triple hashtag (`###`) line is a request delimiter: what comes after it is for a different request. + +* The POST request needs headers and a body. To define those parts of the request, add the following lines immediately after the POST request line: + + ``` + Content-Type: application/json + + { + "name":"walk dog", + "isComplete":true + } + ``` + + The preceding code adds a Content-Type header and a JSON request body. The TodoApi.http file should now look like the following example, but with your port number: + + ```http + @TodoApi_HostAddress = https://localhost:7057 + + POST {{TodoApi_HostAddress}}/todoitems + Content-Type: application/json + + { + "name":"walk dog", + "isComplete":true + } + + ### + ``` + +* Run the app. + +* Select the **Send request** link that is above the `POST` request line. + + ![.http file window with run link highlighted.](~/tutorials/min-web-api/static/9.x/http-file-run-button-vs17.8.0.png) + + The POST request is sent to the app and the response is displayed in the **Response** pane. + + ![.http file window with response from the POST request.](~/tutorials/min-web-api/static/9.x/http-file-window-with-response-vs17.8.0.png) + +# [Visual Studio Code](#tab/visual-studio-code) + +* With the app still running, in the browser, navigate to `https://localhost:{PORT}/swagger` to display the API testing page generated by Swagger. + + ![Swagger generated API testing page](~/tutorials/min-web-api/static/9.x/swagger.png) + +* On the Swagger API testing page, select **Post /todoitems** > **Try it out**. +* Note that the **Request body** field contains a generated example format reflecting the parameters for the API. +* In the request body enter JSON for a to-do item, without specifying the optional `id`: + + ```json + { + "name":"walk dog", + "isComplete":true + } + ``` + +* Select **Execute**. + + ![Swagger with Post request](~/tutorials/min-web-api/static/9.x/swagger-post-1.png) + +Swagger provides a **Responses** pane below the **Execute** button. + + ![Swagger with Post response](~/tutorials/min-web-api/static/9.x/swagger-post-responses.png) + +Note a few of the useful details: + +* cURL: Swagger provides an example cURL command in Unix/Linux syntax, which can be run at the command line with any bash shell that uses Unix/Linux syntax, including Git Bash from [Git for Windows](https://git-scm.com/downloads). +* Request URL: A simplified representation of the HTTP request made by Swagger UI's JavaScript code for the API call. Actual requests can include details such as headers and query parameters and a request body. +* Server response: Includes the response body and headers. The response body shows the `id` was set to `1`. +* Response Code: A 201 `HTTP` status code was returned, indicating that the request was successfully processed and resulted in the creation of a new resource. + +--- + +## Examine the GET endpoints + +The sample app implements several GET endpoints by calling `MapGet`: + +|API | Description | Request body | Response body | +|--- | ---- | ---- | ---- | +|`GET /todoitems` | Get all to-do items | None | Array of to-do items| +|`GET /todoitems/complete` | Get all completed to-do items | None | Array of to-do items| +|`GET /todoitems/{id}` | Get an item by ID | None | To-do item| + +[!code-csharp[](~/tutorials/min-web-api/samples/9.x/todo/Program.cs?name=snippet_get)] + +## Test the GET endpoints + +# [Visual Studio](#tab/visual-studio) + +Test the app by calling the `GET` endpoints from a browser or by using **Endpoints Explorer**. The following steps are for **Endpoints Explorer**. + +* In **Endpoints Explorer**, right-click the first **GET** endpoint, and select **Generate request**. + + The following content is added to the `TodoApi.http` file: + + ```http + GET {{TodoApi_HostAddress}}/todoitems + + ### + ``` + +* Select the **Send request** link that is above the new `GET` request line. + + The GET request is sent to the app and the response is displayed in the **Response** pane. + +* The response body is similar to the following JSON: + + ```json + [ + { + "id": 1, + "name": "walk dog", + "isComplete": true + } + ] + ``` + +* In **Endpoints Explorer**, right-click the `/todoitems/{id}` **GET** endpoint and select **Generate request**. + The following content is added to the `TodoApi.http` file: + + ```http + GET {{TodoApi_HostAddress}}/todoitems/{id} + + ### + ``` + +* Replace `{id}` with `1`. + +* Select the **Send request** link that is above the new GET request line. + + The GET request is sent to the app and the response is displayed in the **Response** pane. + +* The response body is similar to the following JSON: + + ```json + { + "id": 1, + "name": "walk dog", + "isComplete": true + } + ``` + +# [Visual Studio Code](#tab/visual-studio-code) + +Test the app by calling the endpoints from a browser or Swagger. + +* In Swagger select **GET /todoitems** > **Try it out** > **Execute**. + +* Alternatively, call **GET /todoitems** from a browser by entering the URI `http://localhost:{PORT}/todoitems`. For example, `http://localhost:5001/todoitems` + +The call to `GET /todoitems` produces a response similar to the following: + +```json +[ + { + "id": 1, + "name": "walk dog", + "isComplete": true + } +] +``` + +* Call **GET /todoitems/{id}** in Swagger to return data from a specific id: + * Select **GET /todoitems** > **Try it out**. + * Set the **id** field to `1` and select **Execute**. + +* Alternatively, call **GET /todoitems** from a browser by entering the URI `https://localhost:{PORT}/todoitems/1`. For example, `https://localhost:5001/todoitems/1` + +* The response is similar to the following: + + ```json + { + "id": 1, + "name": "walk dog", + "isComplete": true + } + ``` + +--- + +This app uses an in-memory database. If the app is restarted, the GET request doesn't return any data. If no data is returned, [POST](#post) data to the app and try the GET request again. + +## Return values + +ASP.NET Core automatically serializes the object to [JSON](https://www.json.org) and writes the JSON into the body of the response message. The response code for this return type is [200 OK](https://developer.mozilla.org/docs/Web/HTTP/Status/200), assuming there are no unhandled exceptions. Unhandled exceptions are translated into 5xx errors. + +The return types can represent a wide range of HTTP status codes. For example, `GET /todoitems/{id}` can return two different status values: + +* If no item matches the requested ID, the method returns a [404 status](https://developer.mozilla.org/docs/Web/HTTP/Status/404) error code. +* Otherwise, the method returns 200 with a JSON response body. Returning `item` results in an HTTP 200 response. + +## Examine the PUT endpoint + +The sample app implements a single PUT endpoint using `MapPut`: + +[!code-csharp[](~/tutorials/min-web-api/samples/9.x/todo/Program.cs?name=snippet_put)] + +This method is similar to the `MapPost` method, except it uses HTTP PUT. A successful response returns [204 (No Content)](https://www.rfc-editor.org/rfc/rfc9110#status.204). According to the HTTP specification, a PUT request requires the client to send the entire updated entity, not just the changes. To support partial updates, use [HTTP PATCH](xref:Microsoft.AspNetCore.Mvc.HttpPatchAttribute). + +## Test the PUT 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 PUT call. Call GET to ensure there's an item in the database before making a PUT call. + +Update the to-do item that has `Id = 1` and set its name to `"feed fish"`. + +# [Visual Studio](#tab/visual-studio) + +* In **Endpoints Explorer**, right-click the **PUT** endpoint, and select **Generate request**. + + The following content is added to the `TodoApi.http` file: + + ```http + PUT {{TodoApi_HostAddress}}/todoitems/{id} + + ### + ``` + +* In the PUT request line, replace `{id}` with `1`. + +* Add the following lines immediately after the PUT request line: + + ```http + Content-Type: application/json + + { + "id": 1, + "name": "feed fish", + "isComplete": false + } + ``` + + The preceding code adds a Content-Type header and a JSON request body. + +* Select the **Send request** link that is above the new PUT request line. + + The PUT 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 PUT request: + +* Select **Put /todoitems/{id}** > **Try it out**. + +* Set the **id** field to `1`. + +* Set the request body to the following JSON: + + ```json + { + "id": 1, + "name": "feed fish", + "isComplete": false + } + ``` + +* Select **Execute**. + +--- + +## Examine the PATCH endpoint + +Create a file named `TodoPatchDto.cs` with the following code: + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todo/TodoPatchDto.cs"::: + +The `TodoPatchDto` class uses nullable properties (`string?` and `bool?`) to distinguish between a field that wasn't provided in the request versus a field explicitly set to a value. + +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. + +The PATCH endpoint uses a `TodoPatchDto` class with nullable properties to properly handle partial updates. Using nullable properties allows the endpoint to distinguish between a field that wasn't provided (null) versus a field explicitly set to a value (including false for boolean fields). Without nullable properties, a non-nullable bool would default to false, potentially overwriting an existing true value when that field wasn't included in the request. + +> [!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`: + +[!code-csharp[](~/tutorials/min-web-api/samples/9.x/todo/Program.cs?name=snippet_delete)] + +# [Visual Studio](#tab/visual-studio) + +* In **Endpoints Explorer**, right-click the **DELETE** endpoint and select **Generate request**. + + A DELETE request is added to `TodoApi.http`. + +* Replace `{id}` in the DELETE request line with `1`. The DELETE request should look like the following example: + + ```http + DELETE {{TodoApi_HostAddress}}/todoitems/1 + + ### + ``` + +* Select the **Send request** link for the DELETE request. + + The DELETE 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 DELETE request: + +* Select **DELETE /todoitems/{id}** > **Try it out**. +* Set the **ID** field to `1` and select **Execute**. + + The DELETE request is sent to the app and the response is displayed in the **Responses** pane. The response body is empty, and the **Server response** status code is 204. + +--- + +## Use the MapGroup API + +The sample app code repeats the `todoitems` URL prefix each time it sets up an endpoint. APIs often have groups of endpoints with a common URL prefix, and the method is available to help organize such groups. It reduces repetitive code and allows for customizing entire groups of endpoints with a single call to methods like and . + +Replace the contents of `Program.cs` with the following code: + +# [Visual Studio](#tab/visual-studio) + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoGroup/Program.cs" id="snippet_all"::: + +# [Visual Studio Code](#tab/visual-studio-code) + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoGroup_SwaggerVersion/Program.cs" id="snippet_all"::: + +--- + +The preceding code has the following changes: + +* Adds `var todoItems = app.MapGroup("/todoitems");` to set up the group using the URL prefix `/todoitems`. +* Changes all the `app.Map` methods to `todoItems.Map`. +* Removes the URL prefix `/todoitems` from the `Map` method calls. + +Test the endpoints to verify that they work the same. + +## Use the TypedResults API + +Returning rather than has several advantages, including testability and automatically returning the response type metadata for OpenAPI to describe the endpoint. For more information, see [TypedResults vs Results](/aspnet/core/fundamentals/minimal-apis/responses#typedresults-vs-results). + +The `Map` methods can call route handler methods instead of using lambdas. To see an example, update *Program.cs* with the following code: + +# [Visual Studio](#tab/visual-studio) + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoTypedResults/Program.cs" id="snippet_all"::: + +# [Visual Studio Code](#tab/visual-studio-code) + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoTypedResults_SwaggerVersion/Program.cs" id="snippet_all"::: + +--- + +The `Map` code now calls methods instead of lambdas: + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoTypedResults/Program.cs" id="snippet_group"::: + +These methods return objects that implement and are defined by : + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoTypedResults/Program.cs" id="snippet_handlers"::: + +Unit tests can call these methods and test that they return the correct type. For example, if the method is `GetAllTodos`: + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoTypedResults/Program.cs" id="snippet_getalltodos"::: + +Unit test code can verify that an object of type [Ok\](xref:Microsoft.AspNetCore.Http.HttpResults.Ok%601.Value) is returned from the handler method. For example: + +```csharp +public async Task GetAllTodos_ReturnsOkOfTodosResult() +{ + // Arrange + var db = CreateDbContext(); + + // Act + var result = await TodosApi.GetAllTodos(db); + + // Assert: Check for the correct returned type + Assert.IsType>(result); +} +``` + + + +## Prevent over-posting + +Currently the sample app exposes the entire `Todo` object. In production applications, a subset of the model is often used to restrict the data that can be input and returned. There are multiple reasons behind this and security is a major one. The subset of a model is usually referred to as a Data Transfer Object (DTO), input model, or view model. **DTO** is used in this article. + +A DTO can be used to: + +* Prevent over-posting. +* Hide properties that clients aren't supposed to view. +* Omit some properties to reduce payload size. +* Flatten object graphs that contain nested objects. Flattened object graphs can be more convenient for clients. + +To demonstrate the DTO approach, update the `Todo` class to include a secret field: + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoDTO/Todo.cs"::: + +The secret field needs to be hidden from this app, but an administrative app could choose to expose it. + +Verify you can post and get the secret field. + +Create a file named `TodoItemDTO.cs` with the following code: + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoDTO/TodoItemDTO.cs"::: + +Replace the contents of the `Program.cs` file with the following code to use this DTO model: + +# [Visual Studio](#tab/visual-studio) + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoDTO/Program.cs" id="snippet_all"::: + +# [Visual Studio Code](#tab/visual-studio-code) + +:::code language="csharp" source="~/tutorials/min-web-api/samples/9.x/todoDTO_SwaggerVersion/Program.cs" id="snippet_all"::: + +--- + +Verify you can post and get all fields except the secret field. + + + +## Troubleshooting with the completed sample + +If you run into a problem you can't resolve, compare your code to the completed project. [View or download completed project](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/tutorials/min-web-api/samples) ([how to download](xref:fundamentals/index#how-to-download-a-sample)). + +## Next steps + +* [Configure JSON serialization options](xref:fundamentals/minimal-apis/responses#configure-json-serialization-options). +* Handle errors and exceptions: The [developer exception page](xref:fundamentals/error-handling-api#developer-exception-page) is enabled by default in the `Development` environment for Minimal API apps. For information about how to handle errors and exceptions, see [Handle errors in ASP.NET Core APIs](xref:fundamentals/error-handling-api). +* For an example of testing a Minimal API app, see [this GitHub sample](https://github.com/dotnet/AspNetCore.Docs.Samples/tree/main/fundamentals/minimal-apis/samples/MinApiTestsSample). +* [OpenAPI support in Minimal APIs](xref:fundamentals/openapi/aspnetcore-openapi). +* [Quickstart: Publish to Azure](/azure/app-service/quickstart-dotnetcore). +* [Organizing ASP.NET Core Minimal APIs](https://www.tessferrandez.com/blog/2023/10/31/organizing-minimal-apis.html). + +### Learn more + +See + +:::moniker-end diff --git a/aspnetcore/tutorials/min-web-api/static/10/add-info-vs18-6-2.png b/aspnetcore/tutorials/min-web-api/static/10/add-info-vs18-6-2.png new file mode 100644 index 000000000000..7bdb07badc77 Binary files /dev/null and b/aspnetcore/tutorials/min-web-api/static/10/add-info-vs18-6-2.png differ diff --git a/aspnetcore/tutorials/min-web-api/static/10/create-new-project-empty-vs18-6-2.png b/aspnetcore/tutorials/min-web-api/static/10/create-new-project-empty-vs18-6-2.png new file mode 100644 index 000000000000..34e4da9fe6b9 Binary files /dev/null and b/aspnetcore/tutorials/min-web-api/static/10/create-new-project-empty-vs18-6-2.png differ diff --git a/aspnetcore/tutorials/min-web-api/_static/8.x/add-info-vs17.9.0.png b/aspnetcore/tutorials/min-web-api/static/8.x/add-info-vs17.9.0.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/8.x/add-info-vs17.9.0.png rename to aspnetcore/tutorials/min-web-api/static/8.x/add-info-vs17.9.0.png diff --git a/aspnetcore/tutorials/min-web-api/_static/8.x/create-new-project-empty-vs17.8.0.png b/aspnetcore/tutorials/min-web-api/static/8.x/create-new-project-empty-vs17.8.0.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/8.x/create-new-project-empty-vs17.8.0.png rename to aspnetcore/tutorials/min-web-api/static/8.x/create-new-project-empty-vs17.8.0.png diff --git a/aspnetcore/tutorials/min-web-api/_static/8.x/generate-request-vs17.8.0.png b/aspnetcore/tutorials/min-web-api/static/8.x/generate-request-vs17.8.0.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/8.x/generate-request-vs17.8.0.png rename to aspnetcore/tutorials/min-web-api/static/8.x/generate-request-vs17.8.0.png diff --git a/aspnetcore/tutorials/min-web-api/_static/8.x/http-file-run-button-vs17.8.0.png b/aspnetcore/tutorials/min-web-api/static/8.x/http-file-run-button-vs17.8.0.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/8.x/http-file-run-button-vs17.8.0.png rename to aspnetcore/tutorials/min-web-api/static/8.x/http-file-run-button-vs17.8.0.png diff --git a/aspnetcore/tutorials/min-web-api/_static/8.x/http-file-window-with-response-vs17.8.0.png b/aspnetcore/tutorials/min-web-api/static/8.x/http-file-window-with-response-vs17.8.0.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/8.x/http-file-window-with-response-vs17.8.0.png rename to aspnetcore/tutorials/min-web-api/static/8.x/http-file-window-with-response-vs17.8.0.png diff --git a/aspnetcore/tutorials/min-web-api/_static/8.x/swagger-post-1.png b/aspnetcore/tutorials/min-web-api/static/8.x/swagger-post-1.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/8.x/swagger-post-1.png rename to aspnetcore/tutorials/min-web-api/static/8.x/swagger-post-1.png diff --git a/aspnetcore/tutorials/min-web-api/_static/8.x/swagger-post-responses.png b/aspnetcore/tutorials/min-web-api/static/8.x/swagger-post-responses.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/8.x/swagger-post-responses.png rename to aspnetcore/tutorials/min-web-api/static/8.x/swagger-post-responses.png diff --git a/aspnetcore/tutorials/min-web-api/_static/8.x/swagger.png b/aspnetcore/tutorials/min-web-api/static/8.x/swagger.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/8.x/swagger.png rename to aspnetcore/tutorials/min-web-api/static/8.x/swagger.png diff --git a/aspnetcore/tutorials/min-web-api/_static/9.x/add-info-vs17.11.0.png b/aspnetcore/tutorials/min-web-api/static/9.x/add-info-vs17.11.0.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/9.x/add-info-vs17.11.0.png rename to aspnetcore/tutorials/min-web-api/static/9.x/add-info-vs17.11.0.png diff --git a/aspnetcore/tutorials/min-web-api/_static/9.x/create-new-project-empty-vs17.11.0.png b/aspnetcore/tutorials/min-web-api/static/9.x/create-new-project-empty-vs17.11.0.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/9.x/create-new-project-empty-vs17.11.0.png rename to aspnetcore/tutorials/min-web-api/static/9.x/create-new-project-empty-vs17.11.0.png diff --git a/aspnetcore/tutorials/min-web-api/_static/9.x/generate-request-vs17.8.0.png b/aspnetcore/tutorials/min-web-api/static/9.x/generate-request-vs17.8.0.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/9.x/generate-request-vs17.8.0.png rename to aspnetcore/tutorials/min-web-api/static/9.x/generate-request-vs17.8.0.png diff --git a/aspnetcore/tutorials/min-web-api/_static/9.x/http-file-run-button-vs17.8.0.png b/aspnetcore/tutorials/min-web-api/static/9.x/http-file-run-button-vs17.8.0.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/9.x/http-file-run-button-vs17.8.0.png rename to aspnetcore/tutorials/min-web-api/static/9.x/http-file-run-button-vs17.8.0.png diff --git a/aspnetcore/tutorials/min-web-api/_static/9.x/http-file-window-with-response-vs17.8.0.png b/aspnetcore/tutorials/min-web-api/static/9.x/http-file-window-with-response-vs17.8.0.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/9.x/http-file-window-with-response-vs17.8.0.png rename to aspnetcore/tutorials/min-web-api/static/9.x/http-file-window-with-response-vs17.8.0.png diff --git a/aspnetcore/tutorials/min-web-api/_static/9.x/swagger-post-1.png b/aspnetcore/tutorials/min-web-api/static/9.x/swagger-post-1.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/9.x/swagger-post-1.png rename to aspnetcore/tutorials/min-web-api/static/9.x/swagger-post-1.png diff --git a/aspnetcore/tutorials/min-web-api/_static/9.x/swagger-post-responses.png b/aspnetcore/tutorials/min-web-api/static/9.x/swagger-post-responses.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/9.x/swagger-post-responses.png rename to aspnetcore/tutorials/min-web-api/static/9.x/swagger-post-responses.png diff --git a/aspnetcore/tutorials/min-web-api/_static/9.x/swagger.png b/aspnetcore/tutorials/min-web-api/static/9.x/swagger.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/9.x/swagger.png rename to aspnetcore/tutorials/min-web-api/static/9.x/swagger.png diff --git a/aspnetcore/tutorials/min-web-api/_static/add-info.png b/aspnetcore/tutorials/min-web-api/static/add-info.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/add-info.png rename to aspnetcore/tutorials/min-web-api/static/add-info.png diff --git a/aspnetcore/tutorials/min-web-api/_static/add-info2.png b/aspnetcore/tutorials/min-web-api/static/add-info2.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/add-info2.png rename to aspnetcore/tutorials/min-web-api/static/add-info2.png diff --git a/aspnetcore/tutorials/min-web-api/_static/add-info7-vsmac-2022.png b/aspnetcore/tutorials/min-web-api/static/add-info7-vsmac-2022.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/add-info7-vsmac-2022.png rename to aspnetcore/tutorials/min-web-api/static/add-info7-vsmac-2022.png diff --git a/aspnetcore/tutorials/min-web-api/_static/add-info7.png b/aspnetcore/tutorials/min-web-api/static/add-info7.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/add-info7.png rename to aspnetcore/tutorials/min-web-api/static/add-info7.png diff --git a/aspnetcore/tutorials/min-web-api/_static/add-info8-vsmac-2022.png b/aspnetcore/tutorials/min-web-api/static/add-info8-vsmac-2022.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/add-info8-vsmac-2022.png rename to aspnetcore/tutorials/min-web-api/static/add-info8-vsmac-2022.png diff --git a/aspnetcore/tutorials/min-web-api/_static/add-info8.png b/aspnetcore/tutorials/min-web-api/static/add-info8.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/add-info8.png rename to aspnetcore/tutorials/min-web-api/static/add-info8.png diff --git a/aspnetcore/tutorials/min-web-api/_static/asp-net-web-dev-2026.png b/aspnetcore/tutorials/min-web-api/static/asp-net-web-dev-2026.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/asp-net-web-dev-2026.png rename to aspnetcore/tutorials/min-web-api/static/asp-net-web-dev-2026.png diff --git a/aspnetcore/tutorials/min-web-api/_static/asp-net-web-dev.png b/aspnetcore/tutorials/min-web-api/static/asp-net-web-dev.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/asp-net-web-dev.png rename to aspnetcore/tutorials/min-web-api/static/asp-net-web-dev.png diff --git a/aspnetcore/tutorials/min-web-api/_static/create-web-api.png b/aspnetcore/tutorials/min-web-api/static/create-web-api.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/create-web-api.png rename to aspnetcore/tutorials/min-web-api/static/create-web-api.png diff --git a/aspnetcore/tutorials/min-web-api/_static/create.png b/aspnetcore/tutorials/min-web-api/static/create.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/create.png rename to aspnetcore/tutorials/min-web-api/static/create.png diff --git a/aspnetcore/tutorials/min-web-api/_static/empty-vsmac-2022.png b/aspnetcore/tutorials/min-web-api/static/empty-vsmac-2022.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/empty-vsmac-2022.png rename to aspnetcore/tutorials/min-web-api/static/empty-vsmac-2022.png diff --git a/aspnetcore/tutorials/min-web-api/_static/empty.png b/aspnetcore/tutorials/min-web-api/static/empty.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/empty.png rename to aspnetcore/tutorials/min-web-api/static/empty.png diff --git a/aspnetcore/tutorials/min-web-api/_static/generate-request.png b/aspnetcore/tutorials/min-web-api/static/generate-request.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/generate-request.png rename to aspnetcore/tutorials/min-web-api/static/generate-request.png diff --git a/aspnetcore/tutorials/min-web-api/_static/http-file-run-button.png b/aspnetcore/tutorials/min-web-api/static/http-file-run-button.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/http-file-run-button.png rename to aspnetcore/tutorials/min-web-api/static/http-file-run-button.png diff --git a/aspnetcore/tutorials/min-web-api/_static/http-file-window-with-response.png b/aspnetcore/tutorials/min-web-api/static/http-file-window-with-response.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/http-file-window-with-response.png rename to aspnetcore/tutorials/min-web-api/static/http-file-window-with-response.png diff --git a/aspnetcore/tutorials/min-web-api/_static/post2.png b/aspnetcore/tutorials/min-web-api/static/post2.png similarity index 100% rename from aspnetcore/tutorials/min-web-api/_static/post2.png rename to aspnetcore/tutorials/min-web-api/static/post2.png