commit
af613fa516
|
@ -1,14 +1,22 @@
|
|||
## Implement the other CRUD operations
|
||||
|
||||
We'll add `Create`, `Update`, and `Delete` methods to the controller. These are variations on a theme, so I'll just show the code and highlight the main differences. Build the project after adding or changing code.
|
||||
In the following sections, `Create`, `Update`, and `Delete` methods are added to the controller.
|
||||
|
||||
### Create
|
||||
|
||||
Add the following `Create` method.
|
||||
|
||||
[!code-csharp[Main](../../tutorials/first-web-api/sample/TodoApi/Controllers/TodoController.cs?name=snippet_Create)]
|
||||
|
||||
This is an HTTP POST method, indicated by the [`[HttpPost]`](/aspnet/core/api/microsoft.aspnetcore.mvc.httppostattribute) attribute. The [`[FromBody]`](/aspnet/core/api/microsoft.aspnetcore.mvc.frombodyattribute) attribute tells MVC to get the value of the to-do item from the body of the HTTP request.
|
||||
The preceding code is an HTTP POST method, indicated by the [`[HttpPost]`](/aspnet/core/api/microsoft.aspnetcore.mvc.httppostattribute) attribute. The [`[FromBody]`](/aspnet/core/api/microsoft.aspnetcore.mvc.frombodyattribute) attribute tells MVC to get the value of the to-do item from the body of the HTTP request.
|
||||
|
||||
The `CreatedAtRoute` method returns a 201 response, which is the standard response for an HTTP POST method that creates a new resource on the server. `CreatedAtRoute` also adds a Location header to the response. The Location header specifies the URI of the newly created to-do item. See [10.2.2 201 Created](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).
|
||||
The `CreatedAtRoute` method:
|
||||
|
||||
* Returns a 201 response. HTTP 201 is the standard response for an HTTP POST method that creates a new resource on the server.
|
||||
* Adds a Location header to the response. The Location header specifies the URI of the newly created to-do item. See [10.2.2 201 Created](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).
|
||||
* Uses the "GetTodo" named route to create the URL. The "GetTodo" named route is defined in `GetById`:
|
||||
|
||||
[!code-csharp[Main](../../tutorials/first-web-api/sample/TodoApi/Controllers/TodoController.cs?name=snippet_GetByID&highlight=1-2)]
|
||||
|
||||
### Use Postman to send a Create request
|
||||
|
||||
|
@ -18,7 +26,7 @@ The `CreatedAtRoute` method returns a 201 response, which is the standard respon
|
|||
* Select the **Body** radio button
|
||||
* Select the **raw** radio button
|
||||
* Set the type to JSON
|
||||
* In the key-value editor, enter a Todo item such as
|
||||
* In the key-value editor, enter a Todo item such as
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -28,20 +36,16 @@ The `CreatedAtRoute` method returns a 201 response, which is the standard respon
|
|||
```
|
||||
|
||||
* Select **Send**
|
||||
|
||||
* Select the Headers tab in the lower pane and copy the **Location** header:
|
||||
|
||||
![Headers tab of the Postman console](../../tutorials/first-web-api/_static/pmget.png)
|
||||
|
||||
You can use the Location header URI to access the resource you just created. Recall the `GetById` method created the `"GetTodo"` named route:
|
||||
|
||||
```csharp
|
||||
[HttpGet("{id}", Name = "GetTodo")]
|
||||
public IActionResult GetById(long id)
|
||||
```
|
||||
The Location header URI can be used to access the new item.
|
||||
|
||||
### Update
|
||||
|
||||
Add the following `Update` method:
|
||||
|
||||
[!code-csharp[Main](../../tutorials/first-web-api/sample/TodoApi/Controllers/TodoController.cs?name=snippet_Update)]
|
||||
|
||||
`Update` is similar to `Create`, but uses HTTP PUT. The response is [204 (No Content)](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html). According to the HTTP spec, a PUT request requires the client to send the entire updated entity, not just the deltas. To support partial updates, use HTTP PATCH.
|
||||
|
@ -50,8 +54,12 @@ public IActionResult GetById(long id)
|
|||
|
||||
### Delete
|
||||
|
||||
Add the following `Delete` method:
|
||||
|
||||
[!code-csharp[Main](../../tutorials/first-web-api/sample/TodoApi/Controllers/TodoController.cs?name=snippet_Delete)]
|
||||
|
||||
The response is [204 (No Content)](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html).
|
||||
The `Delete` response is [204 (No Content)](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html).
|
||||
|
||||
Test `Delete`:
|
||||
|
||||
![Postman console showing 204 (No Content) response](../../tutorials/first-web-api/_static/pmd.png)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
The preceding code:
|
||||
|
||||
* Defines an empty controller class. In the next sections, we'll add methods to implement the API.
|
||||
* Defines an empty controller class. In the next sections, methods are added to implement the API.
|
||||
* The constructor uses [Dependency Injection](xref:fundamentals/dependency-injection) to inject the database context (`TodoContext `) 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.
|
||||
* The constructor adds an item to the in-memory database if one doesn't exist.
|
||||
|
||||
|
@ -20,22 +20,22 @@ These methods implement the two GET methods:
|
|||
Here is an example HTTP response for the `GetAll` method:
|
||||
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Server: Microsoft-IIS/10.0
|
||||
Date: Thu, 18 Jun 2015 20:51:10 GMT
|
||||
Content-Length: 82
|
||||
|
||||
[{"Key":"1", "Name":"Item1","IsComplete":false}]
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Item1",
|
||||
"isComplete": false
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Later in the tutorial I'll show how you can view the HTTP response using [Postman](https://www.getpostman.com/) or [curl](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/curl.1.html).
|
||||
Later in the tutorial I'll show how the HTTP response can be viewed with [Postman](https://www.getpostman.com/) or [curl](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/curl.1.html).
|
||||
|
||||
### Routing and URL paths
|
||||
|
||||
The `[HttpGet]` attribute specifies an HTTP GET method. The URL path for each method is constructed as follows:
|
||||
|
||||
* Take the template string in the controller’s route attribute:
|
||||
* Take the template string in the controller’s `Route` attribute:
|
||||
|
||||
[!code-csharp[Main](../../tutorials/first-web-api/sample/TodoApi/Controllers/TodoController.cs?name=TodoController&highlight=3)]
|
||||
|
||||
|
@ -44,14 +44,14 @@ The `[HttpGet]` attribute specifies an HTTP GET method. The URL path for each me
|
|||
|
||||
In the `GetById` method:
|
||||
|
||||
```csharp
|
||||
[HttpGet("{id}", Name = "GetTodo")]
|
||||
public IActionResult GetById(long id)
|
||||
```
|
||||
[!code-csharp[Main](../../tutorials/first-web-api/sample/TodoApi/Controllers/TodoController.cs?name=snippet_GetByID&highlight=1-2)]
|
||||
|
||||
`"{id}"` is a placeholder variable for the ID of the `todo` item. When `GetById` is invoked, it assigns the value of "{id}" in the URL to the method's `id` parameter.
|
||||
|
||||
`Name = "GetTodo"` creates a named route and allows you to link to this route in an HTTP Response. I'll explain it with an example later. See [Routing to Controller Actions](xref:mvc/controllers/routing) for detailed information.
|
||||
`Name = "GetTodo"` creates a named route. Named routes:
|
||||
|
||||
* Enable the app to create an HTTP link using the route name.
|
||||
* Are explained later in the tutorial.
|
||||
|
||||
### Return values
|
||||
|
||||
|
@ -59,6 +59,6 @@ The `GetAll` method returns an `IEnumerable`. MVC automatically serializes the o
|
|||
|
||||
In contrast, the `GetById` method returns the more general `IActionResult` type, which represents a wide range of return types. `GetById` has two different return types:
|
||||
|
||||
* If no item matches the requested ID, the method returns a 404 error. This is done by returning `NotFound`.
|
||||
* If no item matches the requested ID, the method returns a 404 error. Returning `NotFound` returns an HTTP 404 response.
|
||||
|
||||
* Otherwise, the method returns 200 with a JSON response body. This is done by returning an `ObjectResult`
|
||||
* Otherwise, the method returns 200 with a JSON response body. Returning `ObjectResult` returns an HTTP 200 response.
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
## Overview
|
||||
|
||||
Here is the API that you’ll create:
|
||||
This tutorial creates the following API:
|
||||
|
||||
|API | Description | Request body | Response body |
|
||||
|API | Description | Request body | Response body |
|
||||
|--- | ---- | ---- | ---- |
|
||||
|GET /api/todo | Get all to-do items | None | Array of to-do items|
|
||||
|GET /api/todo/{id} | Get an item by ID | None | To-do item|
|
||||
|POST /api/todo | Add a new item | To-do item | To-do item |
|
||||
|PUT /api/todo/{id} | Update an existing item | To-do item | None |
|
||||
|DELETE /api/todo/{id} | Delete an item | None | None|
|
||||
|GET /api/todo | Get all to-do items | None | Array of to-do items|
|
||||
|GET /api/todo/{id} | Get an item by ID | None | To-do item|
|
||||
|POST /api/todo | Add a new item | To-do item | To-do item |
|
||||
|PUT /api/todo/{id} | Update an existing item | To-do item | None |
|
||||
|DELETE /api/todo/{id} | Delete an item | None | None|
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -16,10 +16,10 @@ The following diagram shows the basic design of the app.
|
|||
|
||||
![The client is represented by a box on the left and submits a request and receives a response from the application, a box drawn on the right. Within the application box, three boxes represent the controller, the model, and the data access layer. The request comes into the application's controller, and read/write operations occur between the controller and the data access layer. The model is serialized and returned to the client in the response.](../../tutorials/first-web-api/_static/architecture.png)
|
||||
|
||||
* The client is whatever consumes the web API (mobile app, browser, etc). We aren’t writing a client in this tutorial. We'll use [Postman](https://www.getpostman.com/) or [curl](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/curl.1.html) to test the app.
|
||||
* The client is whatever consumes the web API (mobile app, browser, etc.). This tutorial doesn't create a client. [Postman](https://www.getpostman.com/) or [curl](https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/curl.1.html) is used as the client to test the app.
|
||||
|
||||
* A *model* is an object that represents the data in your application. In this case, the only model is a to-do item. Models are represented as C# classes, also know as **P**lain **O**ld **C**# **O**bject (POCOs).
|
||||
* A *model* is an object that represents the data in the app. In this case, the only model is a to-do item. Models are represented as C# classes, also know as **P**lain **O**ld **C**# **O**bject (POCOs).
|
||||
|
||||
* A *controller* is an object that handles HTTP requests and creates the HTTP response. This app will have a single controller.
|
||||
* A *controller* is an object that handles HTTP requests and creates the HTTP response. This app has a single controller.
|
||||
|
||||
* To keep the tutorial simple, the app doesn’t use a persistent database. The sample app stores to-do items in an in-memory database.
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
* [ASP.NET Core Web API Help Pages using Swagger](xref:tutorials/web-api-help-pages-using-swagger)
|
||||
* [Routing to Controller Actions](xref:mvc/controllers/routing)
|
||||
* For information about deploying your API, see [Publishing and Deployment](xref:publishing/index).
|
||||
* For information about deploying an API, see [Publishing and Deployment](xref:publishing/index).
|
||||
* [View or download sample code](https://github.com/aspnet/Docs/tree/master/aspnetcore/tutorials/first-web-api/sample). See [how to download](xref:tutorials/index#how-to-download-a-sample).
|
||||
* [Postman](https://www.getpostman.com/)
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
## Register the database context
|
||||
|
||||
In order to inject the database context into the controller, we need to register it with the [dependency injection](xref:fundamentals/dependency-injection) container. Register the database context with the service container using the built-in support for [dependency injection](xref:fundamentals/dependency-injection). Replace the contents of the *Startup.cs* file with the following:
|
||||
In this step, the database context is registered with the [dependency injection](xref:fundamentals/dependency-injection) container. Services (such as the DB context) that are registered with the dependency injection (DI) container are available to the controllers.
|
||||
|
||||
Register the DB context with the service container using the built-in support for [dependency injection](xref:fundamentals/dependency-injection). Replace the contents of the *Startup.cs* file with the following code:
|
||||
|
||||
[!code-csharp[Main](../../tutorials/first-web-api/sample/TodoApi/Startup.cs?highlight=2,4,12)]
|
||||
|
||||
The preceding code:
|
||||
|
||||
* Removes the code we're not using.
|
||||
* Specifies an in-memory database is injected into the service container.
|
||||
* Removes the code that is not used.
|
||||
* Specifies an in-memory database is injected into the service container.
|
|
@ -157,7 +157,7 @@ Think of AlgorithmConfiguration as the top-level factory. The configuration serv
|
|||
|
||||
When CreateNewDescriptor is called, fresh key material is created solely for this call, and a new IAuthenticatedEncryptorDescriptor is produced which wraps this key material and the algorithmic information required to consume the material. The key material could be created in software (and held in memory), it could be created and held within an HSM, and so on. The crucial point is that any two calls to CreateNewDescriptor should never create equivalent IAuthenticatedEncryptorDescriptor instances.
|
||||
|
||||
The AlgorithmConfiguration type serves as the entry point for key creation routines such as [automatic key rolling](../implementation/key-management.md#data-protection-implementation-key-management). To change the implementation for all future keys, set the AuthenticatedEncryptorConfiguration property in KeyManagementOptions.
|
||||
The AlgorithmConfiguration type serves as the entry point for key creation routines such as [automatic key rolling](../implementation/key-management.md#key-expiration-and-rolling). To change the implementation for all future keys, set the AuthenticatedEncryptorConfiguration property in KeyManagementOptions.
|
||||
|
||||
# [ASP.NET Core 1.x](#tab/aspnetcore1x)
|
||||
|
||||
|
@ -169,6 +169,6 @@ Think of IAuthenticatedEncryptorConfiguration as the top-level factory. The conf
|
|||
|
||||
When CreateNewDescriptor is called, fresh key material is created solely for this call, and a new IAuthenticatedEncryptorDescriptor is produced which wraps this key material and the algorithmic information required to consume the material. The key material could be created in software (and held in memory), it could be created and held within an HSM, and so on. The crucial point is that any two calls to CreateNewDescriptor should never create equivalent IAuthenticatedEncryptorDescriptor instances.
|
||||
|
||||
The IAuthenticatedEncryptorConfiguration type serves as the entry point for key creation routines such as [automatic key rolling](../implementation/key-management.md#data-protection-implementation-key-management). To change the implementation for all future keys, register a singleton IAuthenticatedEncryptorConfiguration in the service container.
|
||||
The IAuthenticatedEncryptorConfiguration type serves as the entry point for key creation routines such as [automatic key rolling](../implementation/key-management.md#key-expiration-and-rolling). To change the implementation for all future keys, register a singleton IAuthenticatedEncryptorConfiguration in the service container.
|
||||
|
||||
---
|
||||
|
|
|
@ -16,7 +16,7 @@ uid: tutorials/first-web-api
|
|||
|
||||
By [Rick Anderson](https://twitter.com/RickAndMSFT) and [Mike Wasson](https://github.com/mikewasson)
|
||||
|
||||
In this tutorial, you’ll build a web API for managing a list of "to-do" items. You won’t build a UI.
|
||||
This tutorial builds a web API for managing a list of "to-do" items. A user interface (UI) is not created.
|
||||
|
||||
There are 3 versions of this tutorial:
|
||||
|
||||
|
@ -48,23 +48,23 @@ In the **New ASP.NET Core Web Application - TodoApi** dialog, select the **Web A
|
|||
|
||||
### Launch the app
|
||||
|
||||
In Visual Studio, press CTRL+F5 to launch the app. Visual Studio launches a browser and navigates to `http://localhost:port/api/values`, where *port* is a randomly-chosen port number. Chrome, Edge, and Firefox display the following:
|
||||
In Visual Studio, press CTRL+F5 to launch the app. Visual Studio launches a browser and navigates to `http://localhost:port/api/values`, where *port* is a randomly chosen port number. Chrome, Microsoft Edge, and Firefox display the following output:
|
||||
|
||||
```
|
||||
["value1","value2"]
|
||||
```
|
||||
```
|
||||
|
||||
### Add a model class
|
||||
|
||||
A model is an object that represents the data in your application. In this case, the only model is a to-do item.
|
||||
A model is an object that represents the data in the app. In this case, the only model is a to-do item.
|
||||
|
||||
Add a folder named "Models". In Solution Explorer, right-click the project. Select **Add** > **New Folder**. Name the folder *Models*.
|
||||
|
||||
Note: The model classes go anywhere in your project, but the *Models* folder is used by convention.
|
||||
Note: The model classes go anywhere in in the project. The *Models* folder is used by convention for model classes.
|
||||
|
||||
Add a `TodoItem` class. Right-click the *Models* folder and select **Add** > **Class**. Name the class `TodoItem` and select **Add**.
|
||||
|
||||
Replace the generated code with the following:
|
||||
Update the `TodoItem` class with the following code:
|
||||
|
||||
[!code-csharp[Main](first-web-api/sample/TodoApi/Models/TodoItem.cs)]
|
||||
|
||||
|
@ -76,7 +76,7 @@ The *database context* is the main class that coordinates Entity Framework funct
|
|||
|
||||
Add a `TodoContext` class. Right-click the *Models* folder and select **Add** > **Class**. Name the class `TodoContext` and select **Add**.
|
||||
|
||||
Replace the generated code with the following:
|
||||
Replace the class with the following code:
|
||||
|
||||
[!code-csharp[Main](first-web-api/sample/TodoApi/Models/TodoContext.cs)]
|
||||
|
||||
|
@ -84,17 +84,17 @@ Replace the generated code with the following:
|
|||
|
||||
### Add a controller
|
||||
|
||||
In Solution Explorer, right-click the *Controllers* folder. Select **Add** > **New Item**. In the **Add New Item** dialog, select the **Web API Controller Class** template. Name the class `TodoController`.
|
||||
In Solution Explorer, right-click the *Controllers* folder. Select **Add** > **New Item**. In the **Add New Item** dialog, select the **Web API Controller Class** template. Name the class `TodoController`.
|
||||
|
||||
![Add new Item dialog with controller in search box and web API controller selected](first-web-api/_static/new_controller.png)
|
||||
|
||||
Replace the generated code with the following:
|
||||
Replace the class with the following code:
|
||||
|
||||
[!INCLUDE[code and get todo items](../includes/webApi/getTodoItems.md)]
|
||||
|
||||
|
||||
### Launch the app
|
||||
|
||||
In Visual Studio, press CTRL+F5 to launch the app. Visual Studio launches a browser and navigates to `http://localhost:port/api/values`, where *port* is a randomly chosen port number. If you're using Chrome, Edge or Firefox, the data will be displayed. If you're using IE, IE will prompt to you open or save the *values.json* file. Navigate to the `Todo` controller we just created `http://localhost:port/api/todo`.
|
||||
In Visual Studio, press CTRL+F5 to launch the app. Visual Studio launches a browser and navigates to `http://localhost:port/api/values`, where *port* is a randomly chosen port number. Navigate to the `Todo` controller at `http://localhost:port/api/todo`.
|
||||
|
||||
[!INCLUDE[last part of web API](../includes/webApi/end.md)]
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 51 KiB |
|
@ -10,7 +10,7 @@ namespace TodoApi.Controllers
|
|||
public class TodoController : Controller
|
||||
{
|
||||
private readonly TodoContext _context;
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
public TodoController(TodoContext context)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@ namespace TodoApi.Controllers
|
|||
return _context.TodoItems.ToList();
|
||||
}
|
||||
|
||||
#region snippet_GetByID
|
||||
[HttpGet("{id}", Name = "GetTodo")]
|
||||
public IActionResult GetById(long id)
|
||||
{
|
||||
|
@ -41,6 +42,7 @@ namespace TodoApi.Controllers
|
|||
return new ObjectResult(item);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
#region snippet_Create
|
||||
[HttpPost]
|
||||
public IActionResult Create([FromBody] TodoItem item)
|
||||
|
|
Loading…
Reference in New Issue