Intro
This step by step tutorial teaches you how to build a full ASP.NET Core MVC REST API with .Net Core and Entity Framework.
Prerequisites
Although not absolutely mandatory, (I’d hope anyone with bit of c# dev experience could follow this), some knowledge of the following areas would be good:
- Model – View – Controller, (MVC), pattern
- Entity Framework
- REST API concepts
Completed code can be found on github HERE
User Story
As a developer
I want to develop a REST API with .Net Core
So that I can provide re-usable end points to other apps
Or if you prefer…
A video covering the same content can be found here on my Youtube channel:
What You’ll Learn
When done you should be able to:
- Understand the anatomy of an ASP.NET Core MVC API app
- Understand the Program and Startup classes (app start up and config)
- Use the MVC pattern to create a REST API, (well the ‘M’ and ‘C’ parts!)
- Use Entity Framework Core to perform CRUD operations
Ingredients
- Visual Studio Code (free) or Visual Studio Community (free)*
- .Net Core SDK (at the time of writing 2.2 is the latest version)
- Microsoft SQL Server Express (free)
- Postman (free)
* I use Visual Studio Code, (VS Code), in the worked examples in this tutorial, however you should be able to follow along if the full Visual Studio IDE is your preferred dev environment.
Our API
The API we are going to develop is simple but useful one, (well useful for me anyway!). With my ever advancing years and worsening state of decrepitude, I wanted to write an API that would store command line snippets, (e.g. dotnet new web -n ), as I’m finding it harder and a harder to recall them when needed. So it’ll really become a command line repository that you can query should the need arise.
So each “resource” will have the following attributes:
- Howto: Description of what the prompt will do, e,g. add a fire wall exception
- Platform: Application or platform domain, e.g. Ubuntu Linux, Dot Net Core etc.
- Commandline: The actual command line snippet, e.g. dotnet build
Our API will follow the standard set of Create, Read, Update and Delete, (CRUD), operations common to most REST APIs, as described in the table below:
Verb | URI | Operation | Description |
---|---|---|---|
GET | /api/commands | Read | Read all command resources |
POST | /api/commands | Create | Create a new resource |
GET | /api/commands/{id} | Read | Read a single resource, (by Id) |
PUT | /api/commands/{id} | Update | Update a single resource, (by Id) |
DELETE | /api/commands/{id} | Delete | Delete a single resource, (by Id) |
Starting Empty!
Ok let’s get going…
Make sure you have .Net Core SDK installed, to check this open a command window and type:
dotnet --version
you should see something similar to the following output, (I’m using the integrated command terminal in VS Code).
If you don’t see this, then I’d suggest you google “.net core sdk” and download and install the SDK for your OS, (Windows, Linux or OSX):
Having done that and assuming you have .Net Core SDK installed, we’re going to create an empty web app to host our api.
.Net Core provides a number of “templates” we can use when creating a new project, selecting a particular template will impact any additional “scaffold” code automatically generated.
To see a list of the templates available, type:
dotnet new
You should see something similar to the following:
You’ll notice that there is actually a template called “webapi” that we could use to generate this project… However I felt that as most of the auto-generated scaffold code is important, that we create this ourselves, therefore for this tutorial we’ll be using the “web” template, which effectively is the simplest, empty, ASP .Net template.
So, to generate our new project, type;
dotnet new web -n CommandAPI
Where:
- web is our template type
- -n CommandAPI, names our project and creates our project & folder
You should see something similar to the following:
A folder called “CommandAPI” should have been created, change into this folder and listing it’s contents you should see:
Anatomy of .Net Core Web App
Before we continue with the coding, it’s important to understand the structure of an ASP .Net Core app, so quickly here’s what each file & folder does, (note we’ll be deep-diving the Program & Startup classes in more depth in the next section):
File / Folder | What is it? |
---|---|
.vscode | This folder stores your VSCode workspace settings, so it’s not really anything to do with the actual project. In fact if you’ve chosen to dev this in Visual Studio, you won’t have this folder. |
bin | Location where final output binaries along with any dependencies and or other deployable files will be written to |
obj | Used to house intermediate object files and other transient data files that are generated by the compiler during a build. |
Properties | Contains the the launchSettings.json file. This file can be used to configure application environment variables, e.g. (Development). It is also used to configure how the webserver running your app will operate, e.g. which port it will listen on etc. |
appsettings.json
appsettings.Development.json |
File used to hold, surprise-surprise, “application settings”. In the tutorial that follows we’ll store the connection string to our database here. |
CommandAPI.csproj | The configuration for the project, principally tells us the .Net Core Framework version we’re using along with other Nuget packages, (see cut out below), that the application will reference and use. |
Program.cs | This class configures the “hosting” platform, along with the “Main()” entry point method for the entire app.
Basically we start here! |
Startup.cs | This class is used to configure the application services and the request pipeline. |
Nuget is a package management platform that allows developers to reference and consume external, pre-packaged code that they can use in their apps. For example we’ll be referencing the: Microsoft.EntityFrameworkCore.Tools package in order to fully utilise the Entity Framework Core command line tools.
Program & Startup Classes
The Program Class
As mentioned above this is the main entry point for the entire app, and is used to configure the “hosting” environment. It then goes on to use the Startup class to finalise the configuration of the app.
Let’s take a quick look at the templated code, (that we’re not actually going to change!), and see what it does…
The execution sequence is as follows:
The CreateDefaultBuilder method uses the builder pattern to create a web host, which can specify things like the webserver to use along with selecting the class we use to complete the configuration of the app services etc. In this case we use the default Startup class for this, indeed since the default contents are sufficient for our needs we’ll more on in the interests of brevity.
The Startup Class
The Program class is the entry point for the app, but most of the interesting startup stuff is done in the Startup class. The Startup class contains 2 methods that we should look further at:
- ConfigureServices
- Configure
ConfigurerServices
In .Net Core Asp we have the concept of “services”, which are just objects that provide functionality to other parts of the application. For those of you familiar with the concept of dependency injection, this is where dependencies are registered inside the default Inversion of Control, (IoC), container provided by .Net Core.
Configure
Once services have been registered, Configure is then called to set up the request pipeline. The request pipeline can be built up of multiple middleware components that take (in this case http), requests and perform some operation on them.
Depending on how the multiple middleware components are created, will affect at what stage they get involved with the request and what, (if anything), they do to impact it. Just for completeness, here’s another diagram, (following on from the one above).
Coding Begins
First let’s just ceck that everything is set up and working ok from a very basic start up perspective. To do this from a command line type, (ensure that you’re “in” the project directory):
dotnet run
You should see something similar to the following:
You can see that the webserver host has started and is listening on ports 5000 and 5001 for http and https respectively.
To change that port allocation you can edit the launchSettings.json file in the Properties folder, although I’d suggest that would be a waste of time!
If you go to a web browser and navigate to:
http://localhost:5000
You should see something like:
Not hugely useful, but it does tell us that everything is wired up correctly. Looking in the Configure method of our Startup class we can see where this response is coming from:
Stop our host from listening, (Ctrl+C on windows – think the same for Linux / OSX), and remove the highlighted section of code from our Configure method. And add the following code to our Startup class:
What does this code do?
- A “using” directive to ensure we have access to the Mvc namespace.
- Adds MVC as a shared usable service, we can optionally set the compatibility version, (in this case we’re using .Net Core Framework 2.2)
- Finally we use the MVC service we registered above as part of our Request Pipeline, this will allow us to take advantage of MVC’s features to build our API.
Note: the code is available on Github HERE
As before type:
dotnet run
to run the app, navigate to the same url, and we should get “nothing”.
Call the Postman
Now is probably a good time to get Postman up and running as it’s a useful tool that allows you to have a more detailed look at whats’ going on.
So if you’ve not done so already, go to the Postman web site HERE and download the version most suitable for your environment, (I use the Windows desktop client, but there’s a Chrome plug-in along with desktop versions for other operating systems).
Once it’s up and running,
Click “New”
Then Select “Request”
Give the request a simple name, e.g. “Test Request”:
You’ll also need to create a “Collection” to house the various API requests you want to create, (e.g. GET, POST etc.):
- Click “+ Create Collection”
- Give it an name, e.g. “Command API”
- Select ok, (the tick)
- Ensure you select your newly created collection (not shown)
- Click Save to Command API
You should then have a new tab available to populate with the details of your request. Simply type:
http://localhost:5000
into the the “Enter request URL” text box, ensure “GET” is selected from the drop down next to it, and hit SEND, it should look something like:
If you’ve clicked Send then you should see a response of “404 Not Found”, clicking on the headers tab, you can see the headers returned.
We’ll return to Postman a bit later, but it’s just useful to get it up, running and tested now.
What have we broken?
We’ve not actually broken anything, but we have taken the first steps in setting up our application to use the MVC pattern to provide our API endpoint…
What’s MVC?
I’m guessing if you’re here you probably have some idea of what the MVC, (Model View Controller), pattern is. If not I provide a brief explanation below, but as:
- There are already 1000’s of articles on MVC
- MVC theory is not the primary focus of this tutorial
I won’t go into too much detail.
Model View Controller
Put simply the MVC pattern allows us to separate the concerns of different parts of our application:
- User Interface (the Views)
- Requests & Actions (Controller)
- Data (Model)
In fact to make things even simpler, as we’re developing an API, we won’t even have any views. A high-level representation of this architecture is shown below:
Model Vs. Data Access?
One area that often confused me was the difference between the Model and the Data Access Layer…Maybe because I’m an idiot?
While the 2 are interdependent, they are different. As simply as i can put it:
- The Model represents the data objects our application works with
- The Data Access Layer uses the Models to mediate that data to a persistent layer*, (e.g. SQL Server DB).
Without the Data Access Layer, (and importantly the DB), while we could model data in our app, the data would be lost if for example we had a power cut, (or heaven forbid the app crashed).
* You can have a data access layer that uses an “in memory db” or non-persistent data store so theoretically you can have a data access layer that still doesn’t persist data… For the most part though I think of a data access layer as being the mediator between the application and the, (persistent), data store…
For the remainder of the tutorial all we actually have to do is:
- Create a Controller to manage all our API requests, (see our CRUD actions above)
- Create a Model to represent our resources (in this case our library of command line prompts)
- Create our Data Access Layer – well use a Entity Framework Core and a DB Context object to achieve this.
So what are we waiting for!?
Our Controller
Making sure you are in our main project directory, create a folder called “Controllers”:
Inside the the Controllers folder you just created, create a file called CommandsController.cs
Quick Tip: If you’re using VS Code you can create both folders and files from within the directory explorer, see below:
Just make sure that you create both the folders and files in the correct location, (it can depend what existing item you have selected as to where the file or folder will be created so can get a bit fiddly):
Your directory / file structure should look like:
Ensure that you postfix the CommandsController file with a “.cs” extension.
Both the folder and naming convention of our controller file follow a standard, conventional approach, this makes our applications more readable to other developers, it also allows us to leverage from the principles of “Convention over Configuration”.
To begin with we’re just going to create a simple “action” in our Controller that will return some hard-coded json, (as opposed to serializing data from our db). Again this just makes sure we have everything wired up correctly.
An “Action” essentially maps to our API CRUD operations above.
Your CommandsController class should now look like the following:
Again, if you don’t fancy typing this in, the code is available on Github – HERE.
We’ll come onto what all this means below, but first lets test it…
Ensure that you don’t have the server running from our example above, (Ctrl+c to terminate), save the file, the type:
dotnet build
This command just compiles, (or builds), the code. If you have any errors it’ll call them out here, assuming all’s well you should see:
Now run the app:
dotnet run
Go to Postman, and in the URL window type:
http://localhost:5000/api/commands
Again ensure that “Get” is selected in the drop down, then click “Send”, you should see something like:
- This is the hard coded json string structure returned
- We have a 200OK HTTP Response code, (basically everything is good)
I guess technically you could say that we have implemented an API that services a simple “GET” request! Hooray, but I’m sure most of you want to take the example a little further…
Back to Our Code
Ok so that’s great, but what did we actually do? Let’s go back to our code and pick it apart:
1. Using Directives
We’ve included 2 using directives here to make things simpler:
- System.Collections.Generic (supports IEnumerable)
- Microsoft.AspNetCore.Mvc (supports pretty much everything else detailed below!)
2. Inherit from ControllerBase
Our Controller class inherits from ControllerBase (does not provide View support which we don’t need). You can inherit from Controller also if you like but as you can probably guess this provides additional support fro Views that we just don’t need.
The ControllerBase is further detailed here on MSDN.
3. Set Up Routing
As you will have seen when you used Postman to issue a Get request to our API, you had to navigate to:
http://localhost:5000/api/commands
The convention for api controllers is to use a “route” prefixed with api, followed by the name of this controller. The name of the controller in this case has the preceding “Controller” component removed so it simply becomes “Commands”, therefore our controller can be accessed at …/api/commands
The route attribute decorating our Controller Class provides this functionality.
4. ApiController Attribute
In short decorating our class with this attribute indicates that the controller responds to web API requests, more detail on why you should use this it outlined here.
In order to use this attribute we had to set the “Compatibility” version in our Startup class to 2.1 or greater, (we set to 2.2).
5. HttpGet Attribute
Cast your mind back to the start of the tutorial, and you’ll remember that we specified our standard CRUD actions for our API, and that each of those actions aligns to a particular http verb, e.g. GET, POST, PUT etc.
Decorating our 1st simple action method with [HttpGet], is really just specifying which verb our action responds to.
You can test this, by changing the verb type in Postman to “POST” and calling our API again. As we have no defined action in our API Controller that responds to POST we’ll receive a 4xx HTTP error response.
6. Our Action Result
This is quite an expansive area, and there are multiple ways you can write your “ActionResults”. I’ve just opted for the “ActionResult” return type which was introduced as part of .Net Core 2.1.
A decent discussion on why you’d use this over IActionResult is detailed by Microsoft here.
In short you’ll have an ActionResult return type for each API CRUD action.
Synchronous Vs Asynchronous?
In addition, you can also specify these actions in an Asynchronous way, (I’ve opted for the arguably simpler Synchronous methodology). Again, discussion of this is outside the scope of this tutorial.
Lambda Expressions
I could have written the action method in the following way to provide the same functionality:
[HttpGet] public IEnumerable Get() => new string[] {"this", "is", "hard", "Coded"};
Again a discussion on this is outside the scope of what I want to cover, but just wanted to bring your attention to the fact you may see API Controller Actions written in this way.
if you’re interested in more detail there’s an article here on MSDN.
Our Model
Ok so we’ve doe the “Controller” part of the MVC pattern, (well a bit of it, it’s still not fully complete – but the groundwork is in), so let’s turn our attention quickly to the Model part of the equation.
Just like with our Controller, the first thing we want to do is create a Models folder in our main project directory.
Once you’ve done that, create a file in that folder and name it Command.cs, your directory and file structure should look like this:
Once created, lets code up our “Command” model – it’s super simple and when done should look like this:
As promised, very simple, just be sure that you’ve specified the correct namespace:
CommandAPI.Models
The rest of the class is a fairly simple model that we’ll use to store our command line snippets. Possibly the only thing really of note is the Id attribute.
This will form the Primary Key when we eventually create a table in our SQL Server Db, (noting this is required by Entity Framework Core.)
Additionally it conforms to the concept of “Convention over Configuration”. I.e. we could have named this attribute differently, but it would potentially require further configuration so that Entity Framework could work with it as a primary key attribute. Naming it this way however, means that we don’t need to do this.
Tying it together
Ok so we have:
- A Controller (it only returns hard-coded data)
- A Model (doesn’t do much at the moment)
It all seems rather dis-jointed…
So for me the component that ties all this together is the data access component of the solution, so there are a few steps we need to take in order to be successful here.
Database
Now as alluded to above, we don’t really need a persistent data store to get an API demo working, but for me if I didn’t provide that as part of an example, I’d feel the tutorial was incomplete.
Anyway I decided to use Microsoft SQL Server for our repository basically because:
- I like SQL Server
- I know SQL Server
- I already have it installed
The good news for you is that if you’re running windows, (and now Linux!), you can install SQL Server for free, just google: “Microsoft SQL Express download” and you’ll be taken to the download site, installing is also very easy, (at least on Windows).
The other good news is that if you can’t or don’t want to install SQL Server, the approach we’re taking should be easily adaptable to other relational database management platforms, (although I don’t cover that here).
So I’m now going to assume you have SQL Server Installed, (I also install the management tool suite – currently this is only available on Windows though).
Firing up SQL Server Management Studio, after connecting and authenticating to our server you should see something similar, (if this is a new install for you, you won’t yet have any user-created databases):
- Our SQL Server Instance
- Databases I’d previously created for other projects, (you may not have any – yet!)
Entity Framework Core Command Line Tools
We’re going to make use of what’s called the Entity Framework Core Command Line tools, (they basically allow you to create migrations, update the database etc, don’t worry if you don’t know what that means yet!). Just trust me, we need the tools!
To add them:
Open the “CommandAPI.csproj” file, you should find this in the project root. Remembering the “Anatomy of .Net Core Web App” section above, the “.csproj” file is where we add any references to additional Nuget packages we want to use…
Opening that file you should see something similar to the following:
- Tells us the Target .Net Core Framework we’re using, this is 2.2
- Lists the existing packages we’ve referenced (we need to add one here)
So in the ItemGroup section, add the following entry:
So you’re .csproj file should look similar to the following:
Ensure you save the file, then at the command line type:
dotnet build
To check that the Entity Framework command line tools are available type:
dotnet ef
You should see something similar to the following:
Create Our DB Context
The next step in producing the data access layer via Entity Framework Core, (EFC), is to create a Database Context Class. As I’ve already written an introduction tutorial to Entity Framework so I’m not going to cover that now, pop over to the post and have a read HERE.
Note: We’re going to use the .Net Command line, (with the EFC tools we just installed above), to generate migrations, update the db etc, so they differ to the command line prompts mentioned in my Entity Framework article, (they package manager console commands – more on that later…)
The concepts however, remain the same – specifically the narrative on the DBContext class. I will cover the “new” .Net Command Line prompts required below.
In short though the DBContext class acts as a representation of the Database and mediates between our data Models and their existence in the DB.
We’ll create the DBContext class in the “Models” folder, so create a new file called: CommandContext.cs and place it in the Models folder, it should look like this:
Now update the code in the CommandContext.cs file to mirror the following, be sure to include the “using” directive:
I’ve highlighted some points of note:
- Ensure you have the EntityFrameworkCore using statement.
- Our class inherits from “DBContext”
- Really important we create a “DbSet” of Command objects
While you can think of the DBContext class as a representation of the Database, you could think of a DbSet as a representation of a table in the Database. I.e. we are telling our DbContext class that we want to “model” our Commands in the Database, (so we can persistently store them as a table).
This means that we can choose which classes, (model classes), we want to put under DBContext control and hence represent in the DB.
Update appsettings.json
Ok so that’s all well and good, but there is still a disconnect between the physical SQL Server DB and our application, (specifically our CommandContext class).
For those of you that have done a bit of programming before, you won’t be surprised to hear that we have to provide a “Connection String” to our application that essentially tells it how to connect to our DB Server.
In this instance that is done via the appsettings.json file.
So open appsettings.json and edit it to look like this, note that you’ll actually have to supply the name of your SQL Server database, (I’ve highlighted in bold where this should be.
{ "Data": { "CommandAPIConnection": { "ConnectionString" : "Server=;Database=CmdAPI;Trusted_Connection=True;MultipleActiveResultSets=true" } } }
So your file should look something like this, again note the example below is using my SQL Server DB Name.
Note: if you’re SQL Server instance name is something like:
WORKSTATION\SQLEXPRESS
You’ll need to ensure that you put a double ‘\’ in the connection string above, so that it’ll look something like:
WORKSTATION\\SQLEXPRESS
It would also be worth running your appsettings.json file contents through something like : http://jsoneditoronline.org/ just to ensure that you have everything correct, e.g.:
Note in our example above we’ll be using Windows Integrated security to connect to the DB, (therefore I don’t have to explicitly supply user name and password details). If you’re using SQL Server Authentication then you’ll need to change the connection string to reflect this.
Where’s our database?
You may have noticed that we have provided a connection to our database server, but that we have also specified the database too, (CmdAPI), – where is that database? Recal from the section above that I saw the following when I used SQL Server Management Studio to connect to my SQL Server:
- Is the name of my SQL Server instance, (the actual server)
- Is a list of databases on that server (again you may have none)
Nowhere on that list of databases is the database we supplied in our connection string: CmdAPI. That’s because it will be created when we migrate and update in the sections that follow…
Revisit the Startup Class
So to recap we have:
- A Database Server, (but actually no CmdAPI “database” as yet!)
- A Model (Command)
- DBContext (CommandContext)
- DBSet (CommandItems)
- Connection String to our database server
The last few things we have to do are:
- Point our DBContext class to the connection string (currently it’s not aware of it)
- “Register” our DB context class in Starup->ConfigureServices so that it can be used throughout our application as a “service”.
In order to supply our connection string, (current in appsettings.json), to our DBContext class we have to update our Startup class to provide a “Configuration” object for use, (we use this configuration object to access the connection string).
Side note: Casting your mind back to the start of the tutorial, when we had a choice if project templates?
We chose “web” to provide us with an empty shell project. Well if you had chosen “webapi”, the “Configuration” code we’re about to introduce below, would have been provided as part of that project template…
Ok so add the following lines to your Startup class so it looks like the following:
- Add a new using directive: Microsoft.Extensions.Configuration
- Create an IConfiguration interface and set up in the constructor
As this code is using Dependency Injection, (a tutorial for another time!), I’m not going to go into more detail of how this works, effectively though it’s providing us with the fabric to read config data from appsettings.json, you’ll see this next.
For more information on the IConfiguration interface the MSDN docs are here.
The last thing we have to do is register our DBContext in the ConfigureServices method and pass it the connection string, (via a configuration interface). So add the following line to your ConfigureServices method in your Startup class:
1. Two New Using Directives
You need to add:
- Microsoft.EntityframeworkCore (gives us access to “UseSqlServer”)
- CommandAPI.Models (gives us access to our DBContext class CommandContext)
2. Registration of Our DBContext
- Add, (or registers), our DBContext class as a service via Dependency Injection
- Specifies we’re using “SQL Server”
- References our JSON Configuration structure to supply the connection string
Phew! Quite a bit of coding there to wire up everything, we’re almost done, but now we need to move on to “migrating” our model from the app to the DB…
Create and Apply Migrations
So we should have everything in place to to create our database and the table containing our Command Objects.
Code First Vs Database First
Just another side note, you may hear about “Code First” and “Database First” approaches when it comes to Entity Framework, again I’d refer you to my previous post or video on what this is detail, but in short it speaks to whether:
- We write “code first” then “push” or “migrate” that code to create our database and tables, or:
- We create out Database and tables first and “import” or “generate” code (models), from the DB
Here we are using “code first”, (we’ve already created our command model), so we now have to “migrate” that to our db, we do this via something called, drum roll… Migrations!
So go to your command line, and ensure that you are “in” the main project folder, and type the following, (hitting enter when you’re done):
dotnet ef migrations add AddCommandsToDB
Now all being well an number of magical things should have happened here..
First off your command line should report something along the lines of:
Next you should see an new folder appear in our project structure, called “Migrations”:
Specifically you should make note a new file called: date time stamp + migration name_.cs e.g.:
20190104023708_AddCommandsToDB.cs
It is the contents of this file that when applied to the Db will create our new table, (and as it’s the first time our actual Database too). A quick look in the file and you’ll see:
- An “Up” method. Basically this method is called to create new stuff
- A “Down” method. Used to roll back the changes made in the Up method
- The creation of a table and it’s columns, noticing the nature of the “Id” column
Entity Framework is a huge area so I’m not going to go into any more detail than that, except to refer you one last time to my prior article.
Note: at this stage we still do not have the CmdAPI database created, that comes next..
Finally all that’s left to to is “update the database” to apply our changes to do this type:
dotnet ef database update
More magic, (don’t worry I’ll spare you that guy again), this time the following things happened:
- Our Database was created
- Our CommandItems Table was created
- A Migration History Table is created (used to keep track of the migrations that have been run)
This is reflected by our command line output, (i’ve just shown the creation of our CommandItems table):
If we also take a look at our SQL Server instance this is reflected by the fact we have both our CmdAPI database and our table:
Add Some Data
Ok so now we want to add some data to our database. You can script this but this tutorial has gotten longer than expected so I’ll skip that and simply add data manually. Using SQL Server Management Studio, right click your table and select “Edit Top 200 Rows”, you can start to populate some test data.
Note: You do not have to add data for the “Id” column as SQL Server automatically manages this for us.
In terms of the data we should put in, I’d like to circle back to the creation and updating of the DB above, we used the following 2 commands:
dotnet ef migrations add dotnet ef database update
So for example we’d add the following to our table:
Again remember you don’t have to manually enter data for the ID…
Alternatively you can write a SQL INSERT statement to add the data, click “New Query”:
In the new query window, write your SQL:
INSERT INTO CommandItems (HowTo, [Platform], Commandline) VALUES ('Create a new migration', 'Entity Framework Core Command Line', 'dotnet ef migrations add );
Select the SQL and hit F5 to execute it.
Noting that I’ve had to delineate the column “Platform” with square brackets [] as this is a reserved SQL Server word. Again also note I’m not explicitly adding any data for the Id.
If you read my article on Entity Framework, you’ll have noticed by now that the commands used in that tutorial are different to those used here. That’s because in that tutorial, we’re using the “Package Manager Console” in Visual Studio to issue commands for Entity Framework, (not Entity Framework Core / and the .Net Core Command line) – quite confusing I know!
I think therefore just to labour that point let’s add 2 new command line prompts in our DB:
How To | Platform | Command Line |
---|---|---|
Create a new Migration | Entity Framework Package Manager Console | add-migration name of migration |
Apply Migrations to DB (Update Database) | Entity Framework Package Manager Console | update-database |
So now we have the following entries in our database, (hopefully now you can see how potentially useful this API will become!):
Lastly let’s update our controller actions to work with this data!
Revisiting Our Controller
Ok, it’s been a while so this is where we left our controller:
We had 1 HttpGet Action that returned a hard-coded string enumeration. Let’s alter this action so that it uses our DBContext class to go to the database and pull back our “live” data!
Add the following lines to you controller (new stuff is highlighted):
So what’s going on? The first important change is the fact that we create a private instance of a CommandContext class (_context). We then create a constructor for our our controller and using Constructor Dependency Injection we assign an instance of our DBContext to our private instance:
I appreciate this can be confusing, (i get tied up in knots with this stuff), so it’s why it’s important to understand the role of the Startup class and specifically the ConfigureServices method where the registration of services occurs.
In short, our private _context instance is a representation of the CommandContext class that we can then use to access the database.
I’m intending to do a tutorial on Dependency Injection soon
The next code addition, is somewhat more straightforward, I’ve deliberately commented out our original, hard-coded action to see how similar they are:
Instead of expecting a return type of string, we’re now expecting a return type of Command. I’ve also changed the name of the method from Get to GetCommandItems.
Finally, use our DB context to return the contents of our DbSet: CommandItems (essentially an enumeration of Commands).
Let’s save the file, and build our project to test for errors:
dotnet build
Assuming all is well lets run:
dotnet run
And finally trigger a call via Postman, (exactly the same way as before):
That was a long road – bet we have achieved a major milestone!
Our Remaining Actions
Ok so going back to our original spec we have implemented 1 of our actions:
Verb | URI | Operation | Description | Coded? |
---|---|---|---|---|
GET | /api/commands | Read | Read all command resources | Yes |
POST | /api/commands | Create | Create a new resource | No |
GET | /api/commands/{id} | Read | Read a single resource, (by Id) | No |
PUT | /api/commands/{id} | Update | Update a single resource, (by Id) | No |
DELETE | /api/commands/{id} | Delete | Delete a single resource, (by Id) | No |
GET /api/commands/n
Next we’ll tackle the 2nd GET Action, the action to return a single resource, here’s how the code looks:
At this stage the code should be relatively easy to follow, the main addition is the use of the ‘{id}’ variable that appears both in the HttpGet attribute decorating the method and also its appearance in the method signature as an expected parameter.
The “{id}’ is a place holder variable for the Command’s unqiue identifier, which will appear in the calling URL pattern, e.g.:
http://localhost:5000/api/commands/1
The when GetCommandItem is invoked, this paramter is passed into the method, the rest of the code is pretty straightforward.
Call the Postman
As always we’ll want to test this in Postman, we’ll do 2 tests:
- Supply a valid id in the URL request
- Supply a an invalid, (non existent) if in the URL request
Valid Test Case
Here we’ll supply an id of ‘1’ in our api call, allother settings should remain the same, here’s the resut:
In Valid Test Case
Here we’ll supply an id of ‘9’, (there is no corresponding command in our Db with this id), in our api call, here’s the result
Just before we move on from this, we could have written this method in the following way, (indeed we would write it in a number of different ways!), but here’s and example using the “lambda-type” syntax:
We would get a slightly different result when dealing with invalid cases… any idea why?
POST /api/commands
Ok, let’s move onto something a bit more interesting now and look at the call where we create a new Command by POSTing data… Here’s the code, I’m sure by now you’re understanding what it’s doing!
This method:
- Is decorated with [HttpPost] this time
- Expects to be supplied with a command object
- We’ll POST this as body data via Postman
- We’ll add the supplied object to our DbSet via our DbContext
- Note at this point the database will not have been updated
- We’ll “Save Changes
- This is when the added command in our DbSet is flushed through to our DB
- It will return a command object (CreatedAtAction)
The Postman rings 3 times
OK so let’s use Postman to POST some data to our API. We have a little bit of work to do here
Construct Our JSON Command Object
From the previous valid test with Postman, I’d just copy the json payload from the response and edit it in something like http://jsoneditoronline.org/ so:
Set Up Postman to make the Call
Take a look at how I set up my Postman client in readiness to make the call, I explain the set up below:
- Ensure that you have “POST” selected as your verb
- Check that the URL is correctly formed, (in this case there is no ‘id’)
- On the “Body” tab, select “Raw” and then “JSON (application/json)”
- Paste your well-formed json into the Body text box (note that there is no ‘id’ attribute)
- A header will be added automatically when you select “JSON (application/json)” in step 3
All that’s left to do now is test it, (making sure you have successfully built and run your app):
- We get a HTTP 201 – Created response
- We are returned the full json object too
Checking out the headers tab, we see:
The most interesting aspect of this is that we are provided a full URL (or URI if you prefer), to the newly created resource, (i.e you could use this url with our 2nd GET action)
PUT api/commands/n
Ok the PUT verb allows us to update an entire resource, i.e. you have to supply the whole object in order to update it. That means even if you only update 1 attribute you still have to supply the entire object, (this is why the PATCH verb was created as the PUT verb was acknowledged inefficient).
Irrespective, let’s just work with PUT for now, the code is as follows, first add the Microsoft.EntityFrameworkCore using directive at the top of your code, this is referenced by our PUT Action…
Next create the follow Action Result method:
Some points of note with this one:
- We decorate the method with [HttpPut(“{id}”)] which means:
- We expect the PUT Verb
- We expect the unique id of the resource we want to update
- The Action Result returns “NoContent”
- This is per the http specification
- The Action Result method expects:
- id (derived from the URL)
- Command Object (supplied via the request body)
- Assuming we have a matching id, we change the Command Object and mark it’s state as modified, (this is so when we save changes, they’ll be flushed through to the DB)
Test In Postman
Ok we want to ensure that we update an existing command in our database, so I’m going to use the one I just created and make a minor changes to it: so our Postman set up looks like this:
- Ensure the request verb is set to PUT
- In the JSON body payload you have to provide the id attribute this time, (otherwise you’ll receive a bad request result)
- You also have to provide the unique id in the url, (those of you with a keen eye will have noted that the id has changed from 1006 to 1007 – this is because I accidentally deleted the prior command entry!)
Ensure you app builds and is running with the latest changes, (i.e. ensure you have saved your work before you build), then click send…
The return from Postman doesn’t give too much away but we do get the expected 204 No Content response. Checking directly in the DB however, (or you could re-query via our api), shows us that the updates were a success!
DELETE /api/commands/n
The last action we need to implement is our DELETE action, the code is as follows:
This method:
- Is decorated with [HttpDelete(“{id}”) as it expect the DELETE verb and additionally a unique id in the url identify the resource we want to delete
- Interestingly it returns the command object we deleted in the return payload
- We don’t have to supply a body text json payload to delete a resource, (we only need the id)
- We remove the valid command item from our DBContext, then save the changes out to our db
Our Postman Set Up
Our postman set up is as follows:
- Ensure yo have selected DELETE
- Ensure you’re providing a valid id vai the url
- Our body and headers are cleared
Ok so now let’s do our final test…
Success! We are returned the very object we wanted to delete in the response, but looking in our db, we can see it has been removed.
2019-01-04_18-05-32.jpg
Final Word
That’s it! Any comments please leave them below – cheers for now.