Creating Web API in Asp.net Core 3.0 using Code First Approach and In-Memory Database


In code first approach firstly we will write the Model and Context class then Framework will create database and required code for us.

In this demo, I m using Asp.net core 3.0 web api and In-memory database for just testing the web api concept.

Step 1 : Create the asp.net core web api project like this

Step 2: In Solution Explorer, right-click the project. Select Add > New Folder. Name the folder Models and Add the class Emp



namespace EmpApiDemo.Models
{
    public class Emp
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public string EmailId { get; set; }
    }
}

Step 3:: Add the following package from Nuget for EF code first and In-Memory Database like this

In the above package Microsoft.EntityFrameworkCore.SqlServer is used for doing database operation with Sqlserver.

Microsoft.EntityFrameworkCore.InMemory: is used for creating the sql database In-Memory. This is generally useful while creating the demo for POC.

Step 4: In same model folder add the EmpContext.cs file and write the code like this

using Microsoft.EntityFrameworkCore;

namespace EmpApiDemo.Models
{
    public class EmpContext : DbContext
    {
        public EmpContext(DbContextOptions<EmpContext> options)
            : base(options)
        {
        }

        public DbSet<Emp> Emps { get; set; }
    }
}

Step 5: Register the database context in Startup.cs file like this

Step 6: Create the Web Api Controller i.e. EmpsController using Scaffold like this

Now this will auto generate the CRUD operation web api code for us like this

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

namespace EmpApiDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmpsController : ControllerBase
    {
        private readonly EmpContext _context;

        public EmpsController(EmpContext context)
        {
            _context = context;
        }

        // GET: api/Emps
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Emp>>> GetEmps()
        {
            return await _context.Emps.ToListAsync();
        }

        // GET: api/Emps/5
        [HttpGet("{id}")]
        public async Task<ActionResult<Emp>> GetEmp(long id)
        {
            var emp = await _context.Emps.FindAsync(id);

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

            return emp;
        }

        // PUT: api/Emps/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        [HttpPut("{id}")]
        public async Task<IActionResult> PutEmp(long id, Emp emp)
        {
            if (id != emp.Id)
            {
                return BadRequest();
            }

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

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

            return NoContent();
        }

        // POST: api/Emps
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        [HttpPost]
        public async Task<ActionResult<Emp>> PostEmp(Emp emp)
        {
            _context.Emps.Add(emp);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetEmp", new { id = emp.Id }, emp);
        }

        // DELETE: api/Emps/5
        [HttpDelete("{id}")]
        public async Task<ActionResult<Emp>> DeleteEmp(long id)
        {
            var emp = await _context.Emps.FindAsync(id);
            if (emp == null)
            {
                return NotFound();
            }

            _context.Emps.Remove(emp);
            await _context.SaveChangesAsync();

            return emp;
        }

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

Step 7: Now run the application and test on post man like this

For Saving record

For Updating Record

For Deleting Record

For Fetching the Record

In this demo we saw that how to create the Web API CRUD operation using database first approach. We also saw that how to use In-memory database for creating the demo application with sql server.

Advertisement

How to secure the Asp.net Web API 2.0 ? (Part 7)


There are so many ways to secure the Web API. But in this post we will see the Authentication process using “Message Handler”.

As we know in asp.net Web API, before execution of any controller, Httprequest go through the message Handler pipeline sequence as given below image

So if we have to implement the some custom validation logic, it will be better to write code in Message Handler.

What is the Message Handler in asp.net Web API ?

>> A message handler is a class that receives an HTTP request and returns an HTTP response. Message handlers derive from the abstract HttpMessageHandler class.

There will be series of message handlers are chained together. The first handler receives an HTTP request, does some processing, and gives the request to the next handler. At some point, the response is created and goes back up the chain as shown in above image. This pattern is also called a delegating handler.

How to write the Custom Message Handler ?
So many time we will get the scenario to write our own logic in Message Handler to perform some specific task on that scenario we have to create Custom Message handler.

To write the Custom Message Handler we have to

1. Inherit the System.Net.Http.DelegatingHandler
2. Override SendAsync Method of HttpMessageHandler as given below

 protected async override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
   {
      // Here will be our own login
  }

How to implement Custom Authentication process in Message Handler ?

>> From client side we can pass the some Key and Value as Authentication Token. As we know before execution of API controller it will go through the message handler pipeline so in Message handler we have to validate the given Token Value, if it is correct then further execution will happen else we will send the Forbidden request

Step 1: Create some class like APIKeyHandler in Some folder like Security

Step 2: Write the logic as given below in APIKeyHandler class

using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace WebApi_Sample.Security
{
    public class APIKeyHandler : DelegatingHandler
    {
        //set a default API key 
        private const string yourApiValue = "API_Sample_Value";
        

        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            bool isValidAPIKey = false;
            IEnumerable<string> lsHeaders;
            //Validate that the api key exists

            var checkApiKeyExists = request.Headers.TryGetValues("Sample_Key", out lsHeaders);

            if (checkApiKeyExists)
            {
                if (lsHeaders.FirstOrDefault().Equals(yourApiValue))
                {
                    isValidAPIKey = true;
                }
            }

            //If the key is not valid, return an http status code.
            if (!isValidAPIKey)
                return request.CreateResponse(HttpStatusCode.Forbidden, "Sorry you have provide wrong API key.");

            //Allow the request to process further down the pipeline
            var response = await base.SendAsync(request, cancellationToken);

            //Return the response back up the chain
            return response;
        }
    }
} 

Note: In the above code DelegatingHandler is abstract class which has overridden the method of HttpMessageHandler Class.
In the above code we are passing the yourApiValue= “API_Sample_Value” and Key =”Sample_Key”

If the given input from client side is correct then it will Allow the request to process further down the pipeline else it will terminate the request.

Step 3: Register the Custom Message Code in the Application_Startmethod of Global.asax file like this

GlobalConfiguration.Configuration.MessageHandlers.Add(new APIKeyHandler());

Step 4: Run the application and Test the Api Controller get method from PostMan Tool