Disable A Specific User in ASP.NET Core Identity 2.0

I am writing this post simply to document a used case I had a few days ago. I basically wanted to disable a user instead of deleting the meta data from the system.
Since the project was built with regular ASP.Net Core Identity, It didn’t take too long for me to figure this out.

What’s ASP.Net Core Identity?

It is a simple membership system that add login capability to any asp.net Core applications. ASP.Net Core Identity supports external login providers such as Facebook, Twitter, Microsoft, and Google.
In case you would like to learn more about it, feel free to read this post on identity.

Implementation In ASP.NET Core Identity 2.0

I had to add a new property called “IsActive” as shown in the code snippet below to the “ApplicationUser.cs” class to disable the user in the system.

namespace UserApp.Models
{
 //Add profile data for application users by adding properties to the ApplicationUser class
    public class ApplicationUser : IdentityUser
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public bool IsActive { get; set; }
    }
}

Next, I run migration to add the new column to the AspNetUsers table.

Now that I have the new column added to the table, I need to set the IsActive flag during registration.

Where do you update the IsActive flag by default?
Find the action method called RegisterAsync in the “AccountController.cs” and

 public async Task RegisterAsync(RegisterViewModel model, string returnUrl = null)
 {
   ViewData["ReturnUrl"] = returnUrl;
   if (ModelState.IsValid)
   {
        var user = new ApplicationUser
        {
                    FirstName = model.FirstName,
                    LastName = model.LastName,
                    IsActive = true
         };
         var result = await _userManager.CreateAsync(user, model.Password);
         if (result.Succeeded)
         {
           _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            var callbackUrl = Url.EmailConfirmationLink(user.Id, code, Request.Scheme);
            await _emailSender.SendEmailConfirmationAsync(model.Email, callbackUrl);
            logger.LogInformation("User created a new account with password.");
            return RedirectToAction(nameof(ConfirmRegistration));
         }
         AddErrors(result);
     }

     // If we got this far, something failed, redisplay form
     return View(model);
 }

Finally, after running the application and register a brand new user I was able to verify the data in the database. In case you need already have some existing users, you’ll simply need to run an update query to set their flag to active. That’s it!!!

How To Use In-Memory Cache In An ASP.NET Core Web API

Before we can dive into the In-Memory Cache implementation, first, What is caching and when you should consider using it?

Well, caching is basically a technique of storing frequently used data in a temporary storage. Caching can significantly improve the performance and scalability of any application by reducing the time and resources required to load fresh contents. Using that technique will definitely make the end user much happier to use the app.

Types of Caching supported by ASP.Net Core

As you might already know ASP.NET Core supports different types of caching such as In-Memory Cache, Distributed Cache and Response Cache. However, in this post I will take the opportunity to introduce you to how to use In-Memory Cache in an ASP.Net Core Web API app.

How data is stored

When using the In-Memory Cache feature, the data is stored in the memory of Web Server where a web application is being hosted at. It’s good to remember that an application can be hosted on single Server or multiple Servers in a Server Farm. For those of you that have a single server, you should be just fine using In-Memory Cache with no issues because it doesn’t require much to get running, however, if those running on multiple servers on a server farm MUST ensure that the sessions are sticky.

Setting cache expiration time

When adding an item to the cache you set an expiration, this can be an absolute time, a sliding window or the combination of both. Choosing which one to use depends on your scenario.

Example of how to implement In-Memory Cache

To keep thing simple and easy to follow I am going to implement a quick sample API to retrieve the states name using state abbreviation as code. In order to get start simple create a new blank WEB API project in Visual Studio and follow the steps below to fill in the required pieces or you can download the full sample code from github here.

Injecting the dependency from the startup.cs.

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddMemoryCache();
      services.AddMvc();
    }

Now that the In-Memory Cache service has been added, I can access the cache from inside the controllers by simply injecting an IMemoryCache parameter in the constructors.

    private readonly IMemoryCache _cache;

    public StatesController(IMemoryCache memoryCache)
    {
      _cache = memoryCache;
    }

Get Method setup

Next, I need to set my cache inside the get action method which is used to get the name of the state that matches the search criteria.

   [HttpGet("{stateCode}")]
   public async Task Get(string stateCode)
   {
      string state = string.Empty;
      if (!_cache.TryGetValue("CashedStatesList", out Dictionary states))
      {
       Console.WriteLine("Loading from database or json file into cache");

        states =
           JsonConvert.DeserializeObject>(
           await System.IO.File.ReadAllTextAsync("StatesList.json"));

        MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
        {
         AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300), // cache will expire in 300 seconds or 5 minutes
         SlidingExpiration = TimeSpan.FromSeconds(60) // cache will expire if inactive for 60 seconds
        };

        if (states != null)
        _cache.Set("CashedStatesList", states, options);
      }
      else
      {
         Console.WriteLine("***Data Found in Cache...***");
      }

      if (states != null)
      {
         state = states.GetValueOrDefault(stateCode);

         if (string.IsNullOrEmpty(state))
         {
           state = "Not found, please try again.";
         }

      }

      if (string.IsNullOrEmpty(state))
      {
         return NoContent();
      }
      return Ok(state);
  }

Reading from data source

In the code snippet above as you can see the very first if condition is checking against the cache dictionary object to load the states list if exist, otherwise, it will continue and load the states from the json file. To be clear here’s the snippet of code that reads the json file and load the states list.

  states =
           JsonConvert.DeserializeObject>(
           await System.IO.File.ReadAllTextAsync("StatesList.json"));

Set cache expiration

Then, once the data was cached, I set some times to when it will expire which is 5 minutes and if no activity they will expire in 60 seconds. You can set these values according to your requirements.

   MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
   {
     AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(300), // cache will expire in 300 seconds or 5 minutes
     SlidingExpiration = TimeSpan.FromSeconds(60) // cache will expire if inactive for 60 seconds
   };

Then, if you continue reading the code above you will notice where the cache is being set as expected.
Last, as you can see from this simple example, the In-Memory cache is can be very beneficial when hosting an application on a single Server. It stores data on Server and improves application performance. Don’t forget to test your app to not depend solely on cached data.
In case you would like to read more about In-Memory cache, please visit these links below.
Cache in-memory in ASP.NET Core

WordPress Installed in Sub Directory on Windows Server Not Loading

Experience with WordPress windows-server

Setting up and running a WordPress content management system on a Windows Server isn’t always as simple as its Unix counterpart. There’s always something that could go wrong and course I had a pretty interesting experience setting a blog on one of the website I am working on.
Well, I have been working on an ASP.Net Core web application, I wanted to install WordPress in a sub directory to add a blog to the site. At first I thought it would be simple to do so, but I ran into issues after I had installed and setup the whole blog.

WordPress windows-server Error

Well, the problem I was having was that when navigating to the folder which WordPress was installed, I was getting a 404 error as shown below.

This www.example.com page can’t be found No webpage was found for the web address: https://www.example.com/blog
HTTP ERROR 404

Solution

In order to resolve this issue I have read a few post describing the possible cause which was related to the .htaccess file that could be missing on the server. Well, since this was a Windows box, there was a web.config file instead.

I then updated the web.config file on the server with the following content and voila it works. Simply replace “yourdomainname” text with your actual domain.


<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
	 <rule name="WordPress: http://yourdomainname.com/blog" patternSyntax="Wildcard">
	   <match url="*"/>
		<conditions>
		  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true"/>
		  <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true"/>
		</conditions>
		<action type="Rewrite" url="index.php"/>
	   </rule></rules>
    </rewrite>
    <handlers>
      <remove name="aspNetCore"/>
    </handlers>
    <aspNetCore processPath="dotnet" arguments=".\yourdomainname.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout"/>
  </system.webServer>
</configuration>

Quick and Easy Way To Set Authorization Header of HttpClient

Earlier today I was working on this application which requires me to make a few calls to a REST API to get some products back in XML format. In order to accomplish this task, I have instantiated an HttpClient object which to make the call. However, I was getting this security error below saying “Required OAuth credentials not provided”.

 

  900902
  Missing Credentials
  Required OAuth credentials not provided

Solution

Of course the error message is self explanatory, I was missing the authorization token in the header.

string url = "https://api.web.com/search/1.0" + ";
using (var client = new HttpClient())
{
  client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
  client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "my_authorization_token"); ;
  HttpResponseMessage response = client.GetAsync(new System.Uri(url)).Result;
  string responseBody = response.Content.ReadAsStringAsync().Result;
}

RichTextBox Example using Free TinyMCE Editor In ASP.Net Core

In this post, I’d like to take the opportunity to explain briefly how to use the TinyMCE plugin to add Rich TextBox feature to your .Net application. For this specific example I am currently using .Net Core 2.0. Don’t worry if you’re on an earlier .Net version because the implementation is about the same.

First of all, we need a project to be created. I’ll call it TinyMCEDemo which is available on github if you would like to download.
tinymce demo project
Once the project is created, run it and make sure there’s no issues.
For this project I am adding a new Model object called “Book” and a new controller called BooksController. We’ll use the create view to add the book form.

namespace TinyMCEDemo.Models
{
    public class Book
    {
        public string Title { get; set; }
        public string Author { get; set; }
        public string Description { get; set; }
    }
}

After adding the new books controller, run the project and you should see the following book form as shown below.

Now, to install the plugin the simplest way to do so is to reference the CDN endpoint at this location below by adding it to the layout.cshtml file before the site.js reference file.

 
  
  <script src='https://cloud.tinymce.com/stable/tinymce.min.js'></script>
 

Next update the site.js file with the following scripts below.

Since TinyMCE lets you identify replaceable elements via a CSS selector, all you need to do is pass an object that contains a selector to tinymce.init().

In this example, let’s replace all ‘textarea(s)’ with a TinyMCE editor instance by passing the selector ‘textarea’ to tinymce.init() which will enable tinymce to all all textarea in the application.


(function ($) {
    "use strict";
    $(document).ready(function () {
        tinymce.init({
            selector: 'textarea'
        });

    });
})(this.jQuery);

Run the project now and the description should now render the Rich Text format as shown below. If you have any issues please let me know and I’ll try my best to help.

Download TinyMCEDemo Project Here

The current CSharpHelper cannot scaffold literals of type ‘Microsoft.EntityFrameworkCore.Metadata.Internal.DirectConstructorBinding’. Configure your services to use one that can

I am working on a .Net Core 2 application today and tried to apply Add-Migration after I had rollback to an earlier version. Something I’ve done many times with no issues and all the sudden I started seeing this error message below. After researching it for a few minutes, I was able to resolve it pretty quickly. Below are the error message and what was done to rectify it.

Microsoft.EntityFrameworkCore.Migrations[20405]
      No migrations were applied. The database is already up to date.
System.InvalidOperationException: The current CSharpHelper cannot scaffold literals of type 'Microsoft.EntityFrameworkCore.Metadata.Internal.DirectConstructorBinding'. Configure your services to use one that can.
   at Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper.UnknownLiteral(Object value)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateAnnotation(IAnnotation annotation, IndentedStringBuilder stringBuilder)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateEntityTypeAnnotations(String builderName, IEntityType entityType, IndentedStringBuilder stringBuilder)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateEntityType(String builderName, IEntityType entityType, IndentedStringBuilder stringBuilder)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.GenerateEntityTypes(String builderName, IReadOnlyList`1 entityTypes, IndentedStringBuilder stringBuilder)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpSnapshotGenerator.Generate(String builderName, IModel model, IndentedStringBuilder stringBuilder)
   at Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGenerator.GenerateMetadata(String migrationNamespace, Type contextType, String migrationName, String migrationId, IModel targetModel)
   at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
The current CSharpHelper cannot scaffold literals of type 'Microsoft.EntityFrameworkCore.Metadata.Internal.DirectConstructorBinding'. Configure your services to use one that can.

Below is the solution which I have applied. Simply install this package below

Install-Package Microsoft.EntityFrameworkCore.Design

Once done, I was able to run add-migration with no problem as seen below.

Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 2.1.4-rtm-31024 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT OBJECT_ID(N'__EFMigrationsHistory');
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (1ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT OBJECT_ID(N'__EFMigrationsHistory');
Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (0ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT [MigrationId], [ProductVersion]
      FROM [__EFMigrationsHistory]
      ORDER BY [MigrationId];
Microsoft.EntityFrameworkCore.Migrations[20405]
      No migrations were applied. The database is already up to date.
To undo this action, use Remove-Migration.
PM> 

Microsoft Azure: Services Still Down, What’s Going On?

I woke up today to check one of my websites hosted on Microsoft Azure to see a blank page staring at me. I did some preliminary check to make sure I did not break the site over night. Then, I turned to Twitter to see if there’s anything trending about Azure, of course there I found all production services and websites hosted on Azure in the South Central US were down. I tried to access the Azure portal that did not work either, so I could try out anything to remedy the problem.

Below are the updates on the progress for the issue:

Microsoft Azure – Impacted service(s)

Network Infrastructure; Azure Active Directory; SQL Database; Storage; App Service
Impacted region(s)
South Central US; Global
Last update (59 min ago)
CUSTOMER IMPACT: There are currently three identified impact workstreams:

1) Customers with resources in South Central US may experience difficulties connecting to resources hosted in this region. A complete list of impacted services can be found below.
2) Customers using non-regional services, such as Azure Active Directory, may experience intermittent authentication failures in any region.
3) Customers may encounter errors when provisioning new subscriptions.

PRELIMINARY ROOT CAUSE:

1) A severe weather event, including lightning strikes, occurred near one of the South Central US datacenters. This resulted in a power voltage increase that impacted cooling systems. Automated datacenter procedures to ensure data and hardware integrity went into effect and critical hardware entered a structured power down process.
2) As a result, non-regional services, such as Azure Active Directory, encountered an operational threshold for processing requests through the South Central US datacenter. Initial attempts to fail over into other datacenters resulted in temporary traffic congestion for those regions.

ENGINEERING STATUS: Engineers continue to implement the necessary mitigation steps. They have outlined a tentative mitigation workflow:

1) Restore power to the South Central US datacenter (COMPLETED)
2) Recover software load balancers for Azure Storage scale units in South Central US (COMPLETED)
3) Recover impacted Azure Storage scale units in South Central US (In Progress)
4) Recover the remaining Storage-dependent services in South Central US (In Progress)

This mitigation workflow is tentative and subject to change as events develop.

NEXT UPDATE: The next update will be provided by 02:00 UTC 05 Sep 2018 or as events warrant.

Last, I thought I’d share this tweet sent by someone who is also affected by this outage.

How to consume a RESTful API in C#

As a developer you will find yourself in need to consume complex RESTful API as you move forward in your career, so understanding a very basic on might help you get a step ahead. In this short post I will take the opportunity to share how to use the HttpClient class to consume RESTFUL APIs in a C# projects.

What is RESTful API?

Before I proceed into coding, I figured it would be best to describe briefly what exactly is a RESTful API, especially if you just started in web development.
I will try to keep it as simple as possible, so a RESTful API is an application program interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. For instance, most of the services provided by companies such as Google, Facebook, Twitter have their own API which they expose to other third party companies to get information.

HttpClient Class


HttpClient provides a flexible and extensible API for accessing things exposed through HTTP, which fits perfectly a RESTful API.
Make sure to avoid coding your httpClient call as followed, because you run the risk of having System.Net.Sockets.SocketException due to the connection that is being disposed.


using(var client = new HttpClient())
{
}

Make sure to create a single instance of HttpClient in your program since that will help reduce waste of sockets.

Below is a simple console application I’ve put together to read data out of a RESTFUL API for managing a list of country data, such as capital, language, flag image, and currencies which you can download from github and test it yourself.


using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Web;

namespace ReadCountryData
{
class Program
{
public class Currency
{
public string Code { get; set; }

public string Name { get; set; }

public string Symbol { get; set; }
}

public class Country
{
public List Currencies { get; set; }

public string Name { get; set; }

public string Capital { get; set; }
}

static void Main(string[] args)
{
HttpClient http = new HttpClient();

string baseUrl = "https://restcountries.eu/rest/v2/name/";

string queryFilter = "?fields=name;capital;currencies";

Console.WriteLine("Enter your country name:");

string searchTerm = Console.ReadLine();

string url = baseUrl + searchTerm + queryFilter;

HttpResponseMessage response = http.GetAsync(new Uri(url)).Result;

string responseBody = response.Content.ReadAsStringAsync().Result;

var countries = JsonConvert.DeserializeObject>(responseBody);

PrintCountryInfo(countries);
}

public static void PrintCountryInfo(List countries)
{
int counter = 0;

foreach (var country in countries)
{
counter++;

Console.WriteLine("#" + counter);

Console.WriteLine("Country Name:" + country.Name);

Console.WriteLine("Country Capital:" + country.Capital);

foreach (var currency in country.Currencies)
{
Console.WriteLine("Country Currency:" + currency.Name);

Console.WriteLine("Country Code:" + currency.Code);

Console.WriteLine("Country Symbol:" + currency.Symbol);
}

Console.WriteLine(".......................................................");
}
Console.ReadKey();

}
}
}

So, I hope this post help clear some of doubts you had when it comes to consuming a simple RESTful API in C#.

Testing a resful Web API Using Postman

Recently I have worked on how to create a simple Web API service to manage a list of country capitals. I thought it would be beneficial to some if I put together a quick post to show how to test it using postman.

What is Postman?
Postman is a free API debugging tool which makes working with APIs faster and a bit easier. If you don’t already have it installed, feel free to download it so you can follow along.

How do you get Postman?
Postman is free and you can download it at “https://www.getpostman.com/“. Simple download it and following the instructions for the installation. After successful installation, open it and select HTTP Method and enter the URL of the Web API as shown below.

We’ll test the following commands:

[one_third]

HTTP Verbs

GET

GET

POST

PUT

DELETE

[/one_third]

[one_third]

URL/Endpoints

API/Countries

API/Countries/{id}

API/Countries

API/Countries/{id}

API/Countries/{id}

[/one_third]

[one_third_last]

Description

Get all countries

Get a specific country by ID

Add a new country

Update an existing country

Delete a country

[/one_third_last]


POST API/Countries

Let’s add a few countries to the list.

{
"name": "Afghanistan",
"capital":"Kabul"

}

GET API/Countries

I have submitted 6 countries. Let’s get the list of countries that were submitted using the GET verb in Postman.

GET API/Countries/{id}

To find a specific country I need to fetch it by sending the ID in the URL. See below for more.

PUT API/Countries/{id}

Let say I want to change the first country information because of an typo or maybe I just want to change it to a whole different country.
I need to send a PUT to do so.

Let’s verify to see if the first country in the list has been changed.

DELETE API/Countries/{id}

Now let’s try the delete to see what happens.

After deleting country 1, 2, 3,and 4 we now have 2 countries left.

Build a Web API with ASP.NET Core

Recently I was tasked to put a simple WEB API together to manage a list of country capitals, so I decided to put this post together as a walk-through on how I did it.

What is a Web API?

ASP.Net Web API is a framework used to build HTTP services. By using HTTP this makes it easy to access WEB API across the internet, pretty much any platform or devices can can consumed WEB API with no problem.

In order to facilitate the client communication ASP.NET WEB API provides support for the following HTTP resources, such as GET, PUT, POST, DELETE verbs. In case you would like a more thorough explanation you can follow the tutorial from Microsoft here.

What WEB API I will be building?

This a WEB API will be use to manage country capitals information. It will be able to store, update, find and delete countries.

First create an ASP.NET Core project and name it “Countries”.
Create ASP.NET WEB API project

Once done simply build and run the app (CTRL+F5 to launch the app) and should see the same result page below.

Example: http://localhost:port/api/values

["value1","value2"]

Now that we have the foundation and know it’s working, let’s add the country model to the project.

Add the following Model for country:

namespace Countries.Models
{
public class Country
{
public long Id { get; set; }
public string Name { get; set; }
public string Capital { get; set; }
}
}

Add Database context

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


using Microsoft.EntityFrameworkCore;

namespace Countries.Models
{
public class CountryContext:DbContext
{
public CountryContext(DbContextOptions options): base(options)
{
}

public DbSet Countries { get; set; }
}
}

Register Database Context

Next, Register the DbContext via dependency injection (DI) container in order to make it available for use in the controller. ASP.NET core makes it easier since it provides built-in support for dependency injection.
Also, one of the great feature with ASP.NET Core I’ll use here is the “UseInMemoryDatabase” which will create or use a database with the name specified.

Let’s update the startup class with the following snippet.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Countries.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Countries
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext(opt => opt.UseInMemoryDatabase("Countries"));
services.AddMvc();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseMvc();
}
}
}

Next, let’s add the controller to put the methods such as the GET, PUT, POST, and DELETE. Let’s use this option to scaffold the different method for the country model.
Adding a controller to the WEB API
Controller creation
As you can see in the controller constructor, it uses dependency injection to inject the DbContext CountryContext into the controller which makes it available to all the methods inside that controller.


using Countries.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Countries.Controllers
{
[Produces("application/json")]
[Route("api/Countries")]
public class CountriesController : Controller
{
private readonly CountryContext _context;

public CountriesController(CountryContext context)
{
_context = context;
}

// GET: api/Countries
[HttpGet]
public IEnumerable GetCountries()
{
return _context.Countries;
}

// GET: api/Countries/5
[HttpGet("{id}")]
public async Task GetCountry([FromRoute] long id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

var country = await _context.Countries.SingleOrDefaultAsync(m => m.Id == id);

if (country == null)
{
return NotFound();
}

return Ok(country);
}

// PUT: api/Countries/5
[HttpPut("{id}")]
public async Task PutCountry([FromRoute] long id, [FromBody] Country country)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

if (id != country.Id)
{
return BadRequest();
}

_context.Entry(country).State = EntityState.Modified;

try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!CountryExists(id))
{
return NotFound();
}
else
{
throw;
}
}

return NoContent();
}

// POST: api/Countries
[HttpPost]
public async Task PostCountry([FromBody] Country country)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

_context.Countries.Add(country);
await _context.SaveChangesAsync();

return CreatedAtAction("GetCountry", new { id = country.Id }, country);
}

// DELETE: api/Countries/5
[HttpDelete("{id}")]
public async Task DeleteCountry([FromRoute] long id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

var country = await _context.Countries.SingleOrDefaultAsync(m => m.Id == id);
if (country == null)
{
return NotFound();
}

_context.Countries.Remove(country);
await _context.SaveChangesAsync();

return Ok(country);
}

private bool CountryExists(long id)
{
return _context.Countries.Any(e => e.Id == id);
}
}
}