Create a web API with ASP.NET Core 6
Tags: api, dotnet, tutorial, csharp
Published: 2022-10-18 06:42:35


Months ago started working on a freelance project for a freelance customer, I decided to make a custom solution for the project using .Net core 6, React and Postgre SQL. It is a stack that I never had used before so it was a bit of challenging to me.

So today I will start a series of tutorials on how to start working with this stack. 

This tutorial is about creating a Rest API using .Net Core 6.

We need the following tools installed on our computer:

- Visual Studio 2022
- .NET 6.0 SDK
- MS SQL Server
- SSMS

Let’s get started.

## Creating a Web API Project

Open Visual Studio 2022 and select Create a new project and then select ASP.NET Core Web API:

![Starting new project on visual studio 2022](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ennv1pjuu16js7mw9549.png)

then give a name to your project and click Next.

![configure your new project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6jf6oguy84d3scwqz34c.png)

In the next screen, select .NET 6.0 as the framework and click Create:

![select the dot net core version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8by3nftyrtjifb27ahv5.png)

At this point we have a starter project as follows:

![image of solution](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ao1ng3o55cu3tsdckjgm.png)

We are ready to do magic with some code.

First let's run the default project:

Press the start button on visual studio, by default a new browser window will open with a swagger page with the one endpoint existing. 

Otherwise after run you can see the API running on :
https://localhost:7246/swagger/index.html

![Image of project running](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m96h9b00ke4ir5tuthml.png)

When we run the application, the default URL comes from the launchSettings.json:

![image of the project setting where it shows in which address and ports runs locally](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4jrkoqhnisvkmfntps2s.png)

And the result values come from the GET method of the WeatherForecastController:

![iamge of the get endpoint on code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1zpfnv7j0yt9jx9hy684.png)

Adding a Model

In Solution Explorer, right-click the project. 
Select Add -> New Folder and name the folder Models.

Then right-click the Models folder and select Add->Class. 
Name the class Product.cs and click Add.

Next, add the following properties to the class:


![image of the product model](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zo0yj0ndqgod3jmguf94.png)

The Id field is required by the database for the primary key.


## Entity Framework Core
We will use our model with Entity Framework Core (EF Core) to work with a database.

> EF Core is an object-relational mapping (ORM) framework that simplifies the data access code. Model classes don’t have any dependency on EF Core. They just define the properties of the data that will be stored in the database.

In this post, we will write the model classes first and EF Core will create the database. This is called Code First Approach.


Let’s add the EF Core NuGet packages to the project. Right-click on the project and select Manage NuGet Packages… and then install the following packages:

Microsoft.EntityFrameworkCore:
![Image microsoft.EntityFrameworkCore](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5w5f4ru4phd9ivuj44x8.png)

Microsoft.EntityFrameworkCore.SqlServer:
![Image microsoft.EntityFrameworkCore.SqlServer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bfnovms610f5wxojw8m6.png)

Microsoft.EntityFrameworkCore.Tools:
![microsoft.EntityFrameworkCore.Tools](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p483yjkn1o1kw2q97m7k.png)

Adding a Database Context
The database context is the main class that coordinates Entity Framework functionality for a data model. This class is created by deriving from the Microsoft.EntityFrameworkCore.DbContext class.

Now, right-click the Models folder and select Add ->Class. Name the class ProductContext and click Add. Then add the following code to the class:


![Image of ProductContext](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93kpwrh9l36icyidmvz7.png)

The preceding code creates a DbSet<Product> property for the entity set.

In Entity Framework terminology, an entity set typically corresponds to a database table and an entity corresponds to a row in the table.

The name of the connection string is passed into the context by calling a method on a DbContextOptions object. For local development, the ASP.NET Core configuration system reads the connection string from the appsettings.json file.

We need to add our connection string to the appsettings.json. I will use the local SQL server instance in my machine and we can define the connection string as follows:


![image of connection string](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6sclouhz8nf05e86k0w2.png)

Now, we will register our database context to the built-in IOC container. Add the following code to Program.cs:

![Image of program after adding connection to dependency injection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5rngkpsjgv83ug3o6z2p.png)

## Creating Database with Migrations
Now, we will create the database using the EF Core Migrations feature.

First, we will add an initial Migration.

Open Tools -> NuGet Package Manager > Package Manager Console(PMC) and run the following command in the PMC:

`Add-Migration Initial`

The Add-Migration command generates code to create the initial database schema which is based on the model specified in the ProductContext class. The Initial argument is the migration name and any name can be used.

After running the command, a migration file is created under the Migrations folder:

![image of migration command executed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4l3h70mambrviaytivdo.png)



As the next step, run the following command in the PMC:

`Update-Database`

The `Update-Database` command runs the Up method in the Migrations/{time-stamp}_Initial.cs file, which creates the database.

Now, we will check the database created. Open View -> SQL Server Object Explorer.

You will see the newly created database as below:

![Image description] (https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4mr476scs20j9jtben3k.png)

As you see, the Product table and the Migrations History table are created automatically. Then a record is inserted into the migration history table to show the executed migrations on the database.

## Creating API Controller and Methods
In this section, we will create the Products API Controller and add the methods to it, and also will test those methods.

Let’s add the controller first. Right-click on the Controller folder and select Add -> Controller.. and then select API Controller - Empty as below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3j5uu14qcwfrq0nr8r8k.png)

Click Add and give a name to your controller on the next screen.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p5fep41lmeq119fi1bse.png)

ProductsController is created as below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1usvwbj09uzmh43j79v8.png)

As you see, the class is decorated with the [ApiController] attribute. This attribute indicates that the controller responds to web API requests.

ProductsController class inherits from ControllerBase.

Next, we will inject the database context mentioned in the previous section through the constructor of the controller. Add the following code:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i66fngo1hclfqhfp3xdp.png)

Now, we will add CRUD (create, read, update, and delete) action methods to the controller. 

Let’s start with the GET methods.

## GET Method
Add the following code to the ProductsController:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0itnh25ercrrulum22c7.png)

`GetProducts` method returns all the products and `GetProductById(int id)` method returns the product having the Id given as input. They are decorated with the [HttpGet] attribute which denotes that a method responds to an HTTP GET request.

The return type of the GetProduct methods is ActionResult<T> type. ASP.NET Core automatically serializes the object to JSON and writes the JSON into the body of the response message. The response code for this return type is 200, assuming there are no unhandled exceptions. Unhandled exceptions are translated into 5xx errors.

## Routing and URL Paths

The URL path for each method is constructed as follows:

Start with the template string in the controller’s Route attribute `(Route("api/[controller]"))`. Then replace `[controller]` with the name of the controller, which by convention is the controller class name minus the Controller suffix. For this sample, the controller class name is ProductsController, so the controller name is products.

We can test the app by calling the two endpoints from a browser as follows:

- https://localhost:{port}/api/Products
- https://localhost:{port}/api/Products/{id}

Or we can test them via swagger at `https://localhost:7246/swagger/index.html`

But first you should add some test data through SQL Server Management Studio

We do not need to add data for the Id column as SQL Server automatically handles this for us.

Now, we can test the GET endpoints. Start (Ctlr+F5) the application:

![Image of swagger call](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6elqo1ojh9ffn2373a1b.png)

## POST Method
Add the following code to the ProductsController:

![Image post product](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m39v1xmmumltgw561c69.png)

PostProduct method creates a ptoduct record in the database. The preceding code is an HTTP POST method, as indicated by the [HttpPost] attribute. The method gets the value of the product record from the body of the HTTP request.

The `CreatedAtAction` method:

- Returns an HTTP 201 status code, if successful. 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 product record.
- References the GetProductById action to create the Location header's URI.

## Testing the PostProduct Method

Start the application and then select the POST method:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m56om3w82zhi5klt924h.png)

Response:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/72np6sl9lrvigyfws1mn.png)

Also, we can check this record from the Products table in our local database:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eo5jbl8bfs4um2xb178q.png)


## PUT Method
Add the following code to the ProductsController:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/myeywqx6tkxg9depp39h.png)

## Test the PutProduct Method:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bar8lfth4p8xvae1vp5u.png)

Response:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5fjem4ooi1jdgftaoq4.png)

DELETE Method
Add the following code to the ProductsController:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdeekn3e34wa9jwkdj46.png)

## Testing the DeleteProduct Method

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w54he7yst5duhdqv5g24.png)

Response:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vkc8jznrjddixrfhv5jt.png)

Now we have implemented the main CRUD actions for our Product entity.

I hope you found this post helpful.