DEV Community

Cover image for .NET Core 3.1 Web API & Entity Framework Jumpstart - Part 1
Patrick God
Patrick God

Posted on • Updated on

.NET Core 3.1 Web API & Entity Framework Jumpstart - Part 1

This tutorial series is now also available as an online video course. You can watch the first hour on YouTube or get the complete course on Udemy. Or you just keep on reading. Enjoy! :)

Introduction

The .NET Core framework is getting better and better and more important in the web development world nowadays.

Almost every request I get for new web development projects is asking for knowledge in .NET Core, including Web API and Entity Framework Core.

So knowing the fundamentals of back end web development with .NET Core can be highly beneficial to your career. And that’s where this tutorial series comes in.

In a short period, you will learn how to set up a Web API, make calls to this Web API and also save data persistently with Entity Framework Core and the help of Code First Migration.

We will get right to the point, you will see every single step of writing the necessary code and by the end of this tutorial series, you will have what it takes to say ‘yes’ to all the .NET Core project requests from any recruiter.

The only tools you need in the beginning are Visual Studio Code and Postman - both are available for free.

We will use Visual Studio Code for our implementations and Postman to make calls to the Web API. Both tools are available for Windows, Mac OS, and Linux. And since .NET Core is cross-platform, you can follow this tutorial series on any of these operating systems. (I know, Microsoft and cross-platform, it still surprises me, too.)

The back end application we’re going to build is a small text-based role-playing game where different users can register (we’re going to use JSON web tokens for authentication) and create their own characters like a mage or a knight, update attributes of these characters, set the skills and also let the characters fight against each other to see who’s better.

So, I hope you’re ready for your new skills and your new projects. Let's start!

Tools

The only tools we need for now are Visual Studio Code and Postman. Additionally to that, you have to download and install the .NET Core 3.1 SDK.

VS Code can be found on https://code.visualstudio.com/.
Postman is available on https://www.getpostman.com/.
And the SDK can be downloaded on https://dotnet.microsoft.com/download. Make sure to download .NET Core 3.1 for your operating system.

So please download and install everything and then continue with the next chapter.

Create a new Web API

As soon as the .NET Core SDK, Visual Studio Code and Postman is installed, we can already create our first .NET Core application which will be a Web API right away.

To start, I created a new folder called "dotnet-rpg" - for "dotnet role-playing game". Open the folder in VS Code.

I assume you’re already a bit familiar with Visual Studio Code, if not, feel free to have a look around.

While you're doing that, it might also be a good idea to install certain extensions.

First "C# for Visual Studio Code" by Microsoft itself. This extension will also be suggested by VS Code as soon as you create your first C# application. It includes editing support, syntax highlighting, IntelliSense, Go to Definition, Find all references, just have a look, pretty useful stuff.

Next is "C# Extensions" by jchannon. As the description says, it might speed up the development workflow by adding some entries to the context menu, like Adding a new C# class or interface.

And the last one already is one of my personal favorites, the "Material Icon Theme". This one simply provides lots and lots of cute icons.

Alright, but now let’s create our Web API! We open a new terminal window and then let's have a look at what the dotnet command provides.

With adding a -h you see all the available commands. The one that’s interesting for us right now is the new command, which creates a new .NET project.

But we also got the run command to, well, run our application and also the watch command which can be used together with run to restart the application as soon as we make changes to any file. Quite useful, if you don’t want to stop and start the project by yourself every single time you make any changes.

With dotnet new -h we see all the available templates. There are a lot. For instance the plain old console application, and further down we finally got the Web API. So let’s use it!

.NET Core Templates

We type dotnet new webapi and hit return.

Now we see some files that have been generated for us in the explorer. Let’s go through them real quick.

Alt Text

At the bottom, we see the WeatherForecast class. This is just part of the default Web API project. We don’t really need it, but let’s use this example in a minute.

In the meantime, we get a little popup telling us that we should add some files. Of course, we want to add them.

Add necessary files popup

You should see now, that we got the .vscode folder with the launch.json and the tasks.json. Both are configuration files used for debugging, source code formatters, bundlers, and so on, but not very interesting for us at this moment.

Newly added files

So let’s have a look at the Startup class.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}
Enter fullscreen mode Exit fullscreen mode

Here we find the ConfigureServices and the Configure method. The ConfigureServices configures the app’s services, so a reusable component that provides app functionality. We will register services in the future in this method, so they can be consumed in our web service via dependency injection for instance.

Please don’t mind all these buzzwords right now...

The Configure method creates the app’s request processing pipeline, meaning the method is used to specify how the app responds to HTTP requests. As you can see we’re using HttpRedirection, Routing, and so on. With all these Use... extension methods, we’re adding middleware components to the request pipeline. For instance UseHttpRedirection adds middleware for redirecting HTTP requests to HTTPS.

To make things a bit easier for us in the beginning, let's remove the UseHttpRedirection line or at least comment it out.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    //app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}
Enter fullscreen mode Exit fullscreen mode

The Startup class is specified when the app’s host is built. You see that in the Program class in the CreateHostBuilder() method. Here the Startup class is specified by calling the UseStartup() method.

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}
Enter fullscreen mode Exit fullscreen mode

In the .csproject file we see the SDK, the target framework, in our case .NET Core 3.1 and the root namespace. Later on, we will find additional packages like Entity Framework Core in this file.

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <RootNamespace>dotnet_rpg</RootNamespace>
  </PropertyGroup>


</Project>
Enter fullscreen mode Exit fullscreen mode

Regarding the appsettings.json files we only need to know that we can add and modify some configurations here.

More interesting right now is the launchSettings.json file where the current environment is configured and also the application URL. With this URL, we will find our running web service.

"dotnet_rpg_3._1": {
  "commandName": "Project",
  "launchBrowser": true,
  "launchUrl": "weatherforecast",
  "applicationUrl": "https://localhost:5001;http://localhost:5000",
  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
  }
}
Enter fullscreen mode Exit fullscreen mode

The obj and bin folders can be ignored for now. We find temporary object- and final binary files here.

Very interesting and often used throughout this tutorial series is the Controllers folder. The first controller you see here is the generated WeatherForecast demo controller. We’ll get to the details of controllers later. For now, it’s only important to know, that we can already call the Get() method here.

[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
    var rng = new Random();
    return Enumerable.Range(1, 5).Select(index => new WeatherForecast
    {
        Date = DateTime.Now.AddDays(index),
        TemperatureC = rng.Next(-20, 55),
        Summary = Summaries[rng.Next(Summaries.Length)]
    })
    .ToArray();
}
Enter fullscreen mode Exit fullscreen mode

First API Call

In the terminal, we enter dotnet run. You see, here’s already the URL we’ve seen in the launchSettings.json. So let’s open Chrome and go to http://localhost:5000.

dotnet run results

Well, the result of this URL doesn’t look very nice. That's because we have to access the WeatherForecast controller. So when we go back to VS Code, we see the name of the controller (WeatherForecast - without Controller). We also see the routing attribute ([Route"[controller]"]) to define how to access this controller - we’ll discuss how routes work in a future chapter.

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
// ...
Enter fullscreen mode Exit fullscreen mode

So we just copy the name - WeatherForecast - go back to Chrome, enter the correct route and finally, we get the results.

WeatherForecast results in Chrome

We can also see the results in the console.

WeatherForecast results in the console

Now let's do this with Postman because Postman will be the tool we will use to test our REST calls of the Web API.

If you haven’t already, make yourself a bit familiar with Postman.

The essential part is in the middle. We can choose the HTTP Request Method - in this particular case, it is GET - then enter the URL and hit "Send".

The styling of the result should look similar to the console.

WeatherForecast results in the Postman

Great! So this works. Now let’s move on and build our own web service.

Web API Core

So far you learned how to create a Web API project in .NET Core from scratch and how to make your first API call with Postman.

In the upcoming chapters, we will create a new controller and models for our RPG (role-playing game) characters.

Additionally, we will turn our synchronous calls into asynchronous calls, make use of Data-Transfer-Objects (DTOs) and change the structure of our Web API so that it meets best practices.

But first, let’s have a look at the Model-View-Controller (MVC) pattern, which is the foundation of all this.

The Model-View-Controller (MVC) Pattern

Model-View-Controller or short MVC is a software design pattern that divides the related program logic into three interconnected elements. Let me explain, what every single one of these three elements stands for and how they collaborate.

We start with the model. You could also say, the data. A character in our role-playing game is a model, for instance. It can have an Id, a name, hitpoints, attributes, skills and so on.

public class Character
{
    public int Id { get; set; } = 0;
    public string Name { get; set; } = "Frodo";
    public int HitPoints { get; set; } = 100;
    public int Strength { get; set; } = 10;
    public int Defense { get; set; } = 10;
    public int Intelligence { get; set; } = 10;
}
Enter fullscreen mode Exit fullscreen mode

You as the developer know the code of your model. But the user won’t see your code. That’s where the view comes in. The user probably wants to see a representation of the character in HTML, plain text or amazing 3D graphics - depending on your game. In other words, the view is the (graphical) user interface or (G)UI.

To sum these two up, the model updates the view and the user sees the view. If the model changes, let’s say our character gets another skill or its hitpoints decreased, the view will change, too. That’s why the model always updates the view.

MVC Design Pattern

Now, what’s up with the controller? The controller does the actual work. There you will find most of your code because it manipulates your data or model. In our case, it’s the Web API that will create, update and delete your data.

MVC Design Pattern

Since we won’t have a view except the results of our calls in Postman, we’re going to build our application in the following order: First the model and then the controller. And we will always jump back and forth between those two.

With the help of the view though, the user can manipulate the data, hence properties of the RPG character with buttons, text fields and so on. In a browser game that might be JavaScript code in essence - maybe with the help of frameworks like Angular, React or VueJS.

This JavaScript code, in turn, uses the controller to do the manipulation and save these changes persistently in the database. The manipulated model will update the view, which is then again seen by the user and the circle starts all over again.

MVC Design Pattern

Well, that sums up the MVC pattern. Now we’re going to build our first model.

New Models

The first things we need are new models. We need a model for the RPG character itself and also a model for the type of RPG character, i.e. a character class like Barbarian, Monk, Necromancer and so on.

First, we create a "Models" folder. For the character model, we will create a new class in this Models folder. If you have the “C# Extensions” installed, you can add a new C# class with a right-click, otherwise, you just create a new file.

So right-click the Models folder, then click “New C# Class” and call this class Character.

Character Model

Now let’s add some properties.

    public class Character
    {
        public int Id { get; set; }
        public string Name { get; set; } = "Frodo";
        public int HitPoints { get; set; } = 100;
        public int Strength { get; set; } = 10;
        public int Defense { get; set; } = 10;
        public int Intelligence { get; set; } = 10;
    }

Enter fullscreen mode Exit fullscreen mode

We will also add an RpgClass property, i.e. the type of the character. But first, we have to create a new enum for that.

So let’s add a new C# class called RpgClass and then replace class with enum.

Feel free to add any kind of role-playing class you want to add here. In this example, I use Knight, Mage, and Cleric. The most basic characters you would need I guess. Some melee action, some magic and of course never forget the healer.

    public enum RpgClass
    {
        Knight = 1,
        Mage = 2,
        Cleric = 3
    }
Enter fullscreen mode Exit fullscreen mode

Now when we have the RpgClass enum ready, we can finally add it to the Character model.

    public class Character
    {
        public int Id { get; set; }
        public string Name { get; set; } = "Frodo";
        public int HitPoints { get; set; } = 100;
        public int Strength { get; set; } = 10;
        public int Defense { get; set; } = 10;
        public int Intelligence { get; set; } = 10;
        public RpgClass Class { get; set; } = RpgClass.Knight;
    }
Enter fullscreen mode Exit fullscreen mode

I set the default to the Knight, but again, that’s totally up to you.

Alright, the first models are ready. Let’s add a new controller now and make a GET call to receive our first role-playing game character.

New Controller & GET a New Character

To add a new controller, we create a new C# class in the Controllers folder. Let’s call this class CharacterController.

Before we can start implementing any logic, we have to make this thing a proper controller. To do that, we first derive from ControllerBase. This is a base class for an MVC controller without view support. Since we’re building an API here, we don’t need view support. If, however, we would want to add support for views, we could derive from Controller. But in our case, just make sure to add ControllerBase.

public class CharacterController : ControllerBase
Enter fullscreen mode Exit fullscreen mode

After that, we have to add some attributes. The first one is the ApiController attribute. This attribute indicates that a type (and also all derived types) is used to serve HTTP API responses. Additionally, when we add this attribute to the controller, it enables several API-specific features like attribute routing and automatic HTTP 400 responses if something is wrong with the model. We’ll get to the details when we make use of these features.

[ApiController]
public class CharacterController : ControllerBase
Enter fullscreen mode Exit fullscreen mode

Regarding attribute routing, that’s already the next thing we have to add. Below the ApiController attribute, we add the Route attribute. That’s how we’re able to find this specific controller when we want to make a web service call. The string we add to the Route attribute is [controller]. This means that this controller can be accessed by its name, in our case Character - so that part of the name of the C# class that comes before Controller.

[ApiController]
[Route("[controller]")]
public class CharacterController : ControllerBase
Enter fullscreen mode Exit fullscreen mode

Don't forget to also add the reference Microsoft.AspNetCore.Mvc on top of the file.

using Microsoft.AspNetCore.Mvc;
Enter fullscreen mode Exit fullscreen mode

Alright, let’s get into the body of our C# class. The first thing I’d like to add is a static mock character that we can return to the client. For that, you also have to add the dotnet_rpg.Models reference.

using Microsoft.AspNetCore.Mvc;
using dotnet_rpg.Models;

namespace dotnet_rpg.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class CharacterController : ControllerBase
    {
        private static Character knight = new Character();
    }
}
Enter fullscreen mode Exit fullscreen mode

Next, we finally implement the Get() method to receive our game character.

    [ApiController]
    [Route("[controller]")]
    public class CharacterController : ControllerBase
    {
        private static Character knight = new Character();

        public IActionResult Get()
        {
            return Ok(knight);
        }
    }
Enter fullscreen mode Exit fullscreen mode

We return an IActionResult because this enables us to send specific HTTP status codes back to the client together with the actual data that was requested. In this method, with Ok(knight) we send the status code 200 OK and our mock character back. Other options would be a BadRequest 400 status code or a 404 NotFound if a requested character was not found.

Alright, the code is implemented. Let’s test this now with Postman.

It’s pretty straight forward now. The HTTP method is GET again, the URL is http://localhost:5000/character and nothing else has to be configured.

Hit "Send", and there is our knight!

Result of the first Get() call

Now pay attention to the attribute that was added to our Get() method. Exactly, there is none. When we compare this to the WeatherForecastController, we could have added an [HttpGet] attribute. But it’s not necessary for the CharacterController because the Web API supports naming conventions and if the name of the method starts with Get...(), the API assumes that the used HTTP method is also GET. Apart from that we only have one Get() method in our controller so far, so the web service knows exactly what method is requested.

However, in the next chapter, we’ll have a deeper look at these attributes.


That's it for the first part of this tutorial series. I hope it already was useful to you. To get notified for the next part, simply follow me here on dev.to or subscribe to my newsletter. You'll be the first to know.

See you next time!

Take care.


Next up: Attribute routing, HTTP methods, add a new character with POST, asynchronous calls, and more!

Image created by cornecoba on freepik.com.


But wait, there’s more!

Top comments (21)

Collapse
 
manassehv2 profile image
ManassehV2

Thank you very much Patrick for sharing your knowledge in an interesting way. I went through it form start to end and It helped me a lot. It's good people like you who makes the internet a useful place. Thank you very much once again.

Collapse
 
_patrickgod profile image
Patrick God

Thank you so much for your kind words! Glad I could help. :)

Collapse
 
samselfridge profile image
samselfridge

Hey If anyone is getting the Kestrel error about https: "Unable to start Kestrel.
System.InvalidOperationException: Unable to configure HTTPS endpoint."

I addressed this by commenting out the "app.UseHttpsRedirection()" as mentioned but also had to remove "localhost:5001;" from the applicationUrl in launchSettings.json.

Seems to be working, if things start breaking I'll update this comment with any solution I find.

Collapse
 
_patrickgod profile image
Patrick God

Hi,
Thank you very much for sharing that! :)
Have a good one!
Patrick

Collapse
 
johnziss9 profile image
John

Amazing! I have gone through quite a few .Net Core tutorials but none explained it in such way to understand what everything does clearly.

Keep it up Patrick!

Looking forward to the next one!

Thank you!

Collapse
 
_patrickgod profile image
Patrick God

Your comment makes me happy. Thank you! :)

Collapse
 
ekosetiyo13 profile image
EkoSetiyo13

can i get source code ? pls

Collapse
 
_patrickgod profile image
Patrick God

Hey,

I think I will create a GitHub repository soon with the complete project.
Until then, please refer to the code in the article. It really is the complete thing.

Take care,
Patrick

Collapse
 
ekosetiyo13 profile image
EkoSetiyo13

i get error in response.
addcharacterDTO cannot add in characterDTO.
i dont know what i can do

Thread Thread
 
informagico profile image
Alessandro Magoga

Hi, I think you're missing something in the AutoMapperProfile class.
I uploaded my own source code following this tutorial: github.com/informagico/dotnet-rpg

Hope it can help,
cheers!

Thread Thread
 
ekosetiyo13 profile image
EkoSetiyo13

Hi, Thanks you brother.

Collapse
 
nothingnull profile image
NothingNull • Edited

I have no idea why the response that I received, is "1", not the JSON string of the knight character as your screenshot. I also reviewed your source code and it is the same with mine...

dev-to-uploads.s3.amazonaws.com/i/...

Collapse
 
_patrickgod profile image
Patrick God

That's strange... have you tried to call this URL in the browser? Maybe something's wrong with Postman.

Apart from that, you could try to watch the video tutorial on YouTube: youtu.be/H4qg9HJX_SE

Maybe this helps.

Take care,
Patrick

Collapse
 
zoltanhalasz profile image
Zoltan Halasz

Really nice tutorial. Been through a few, and this is top quality.

Collapse
 
_patrickgod profile image
Patrick God

Thank you very much! :)

Collapse
 
johannescleve profile image
Johannes Cleve

Great tutorial. Can't wait for the next one!

Collapse
 
_patrickgod profile image
Patrick God

Thank you very much! Glad you like it! :)

Collapse
 
aaiing profile image
AAI INGENIERIA

Hi, thanks fot the tutorial, do you have a .net core graphql auth with web tokens?

Collapse
 
_patrickgod profile image
Patrick God

Hey,
I'm afraid I don't, but I put it on the list. So maybe soon. ;)
Take care,
Patrick

Collapse
 
lfin90 profile image
Aleksey Levin

Thanks for this useful material.
Perhaps I found a typo:

For instance UseHttpRedirection adds middleware for redirecting HTTP requests to HTTPS.

Maybe do you mean about UseHttpsRedirection?

Collapse
 
tomekdorobisz profile image
tomekdorobisz

The best jumpstart I found so far. :)