Building Your First Web API With ASP.NET Core MVC And Visual Studio

HTTP is not just for serving up web pages. It’s also a powerful platform for building APIs that expose services and data. HTTP is simple, flexible, and ubiquitous. Almost any platform that you can think of has an HTTP library, so HTTP services can reach a broad range of clients, including browsers, mobile devices, and traditional desktop apps.

In this tutorial, you’ll build a simple web API for managing a list of “to-do” items. You won’t build any UI in this tutorial.

ASP.NET Core has built-in support for MVC building Web APIs. Unifying the two frameworks makes it simpler to build apps that include both UI (HTML) and APIs, because now they share the same code base and pipeline.

Note

If you are porting an existing Web API app to ASP.NET Core, see Migrating from ASP.NET Web API

Sections:

Overview

Install Fiddler

Create the project

Add a model class

Add a repository class

Register the repository

Add a controller

Getting to-do items

Use Fiddler to call the API

Implement the other CRUD operations

Next steps

Overview

Here is the API that you’ll create:

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

The following diagram show the basic design of the app.

The client is whatever consumes the web API (browser, mobile app, and so forth). We aren’t writing a client in this tutorial.

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 simple C# classes (POCOs).

A controller is an object that handles HTTP requests and creates the HTTP response. This app will have a single controller.

To keep the tutorial simple the app doesn’t use a database. Instead, it just keeps to-do items in memory. But we’ll still include a (trivial) data access layer, to illustrate the separation between the web API and the data layer. For a tutorial that uses a database, see Building your first ASP.NET Core MVC app with Visual Studio.

Install Fiddler

We’re not building a client, we’ll use Fiddler to test the API. Fiddler is a web debugging tool that lets you compose HTTP requests and view the raw HTTP responses.

Add a repository class

A repository is an object that encapsulates the data layer, and contains logic for retrieving data and mapping it to an entity model. Even though the example app doesn’t use a database, it’s useful to see how you can inject a repository into your controllers. Create the repository code in the Models folder.

Start by defining a repository interface named ITodoRepository. Use the class template (Add New Item > Class).

Register the repository

By defining a repository interface, we can decouple the repository class from the MVC controller that uses it. Instead of instantiating a TodoRepository inside the controller we will inject anITodoRepository the built-in support in ASP.NET Core for dependency injection.

This approach makes it easier to unit test your controllers. Unit tests should inject a mock or stub version of ITodoRepository. That way, the test narrowly targets the controller logic and not the data access layer.

In order to inject the repository into the controller, we need to register it with the DI container. Open the Startup.cs file. Add the following using directive:

usingTodoApi.Models;

In the ConfigureServices method, add the highlighted code:

// This method gets called by the runtime. Use this method to add services to the container.publicvoidConfigureServices(IServiceCollectionservices){// Add framework services.services.AddMvc();services.AddLogging();// Add our repository typeservices.AddSingleton<ITodoRepository,TodoRepository>();}

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 classTodoController.

Later in the tutorial I’ll show how you can view the HTTP response using the Fiddler tool.

Routing and URL paths

The [HttpGet] attribute specifies that these are HTTP GET methods. The URL path for each method is constructed as follows:

Take the template string in the controller’s route attribute, [Route("api/[controller]")]

Replace “[Controller]” with the name of the controller, which is the controller class name minus the “Controller” suffix. For this sample the name of the controller is “todo” (case insensitive). For this sample, the controller class name is TodoController and the root name is “todo”. ASP.NET MVC Core is not case sensitive.

If the [HttpGet] attribute also has a template string, append that to the path. This sample doesn’t use a template string.

For the GetById method, “{id}” is a placeholder variable. In the actual HTTP request, the client will use the ID of the todo item. At runtime, when MVC invokes GetById, it assigns the value of “{id}” in the URL the method’s id parameter.

Return values

The GetAll method returns a CLR object. MVC automatically serializes the object to JSONand writes the JSON into the body of the response message. The response code for this method is 200, assuming there are no unhandled exceptions. (Unhandled exceptions are translated into 5xx errors.)

In contrast, the GetById method returns the more general IActionResult type, which represents a generic result type. That’s because GetById has two different return types:

If no item matches the requested ID, the method returns a 404 error. This is done by returningNotFound.

Otherwise, the method returns 200 with a JSON response body. This is done by returning anObjectResult.

Use Fiddler to call the API

This step is optional, but it’s useful to see the raw HTTP responses from the web API. In Visual Studio, press ^F5 to launch the app. Visual Studio launches a browser and navigates tohttp://localhost:port/api/todo, where port is a randomly chosen port number. If you’re using Chrome, Edge or Firefox, the todo data will be displayed. If you’re using IE, IE will prompt to you open or save the todo.json file.

Create

This is an HTTP POST method, indicated by the [HttpPost] attribute. The [FromBody]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. CreateAtRoute 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.

We can use Fiddler to send a Create request:

In the Composer page, select POST from the drop-down.

In the request headers text box, add Content-Type:application/json, which is a Content-Typeheader with the value application/json. Fiddler automatically adds the Content-Length header.

In the request body text box, enter the following: {"Name":"<yourto-doitem>"}

Click Execute.

Here is an example HTTP session. Use the Raw tab to see the session data in this format.

Update is similar to Create, but uses HTTP PUT. The response is 204 (No Content). 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.

Delete

[HttpDelete("{id}")]publicvoidDelete(stringid){TodoItems.Remove(id);}

The void return type returns a 204 (No Content) response. That means the client receives a 204 even if the item has already been deleted, or never existed. There are two ways to think about a request to delete a non-existent resource: