action in mvc controller is being called twice for 2 objects

I have a weird scenario happens when I send my ajax request that has 2 objects first time it passes the second obj with the right value while the first object is null then second call it passes the first obj with value and the second obj as null here's my ajax method

I have a weird scenario happens when I send my ajax request that has 2 objects first time it passes the second obj with the right value while the first object is null then second call it passes the first obj with value and the second obj as null here's my ajax method

var serializedForm = $(form).serialize();
var postData = {
    merchTask: obj,
    items: arrItems
};
$.ajax({
    type: "POST",
    url: $(form).attr('action'),
    contentType: "application/json; charset=utf-8",
    dataType:'json',
    data: JSON.stringify(postData),
    success: function (response) { 
        alert('done');
    },
     error: function (xhr, status, error) {
         alert("Oops..." + xhr.responseText);
     }
});    

and here's my action in controller

    public ActionResult EditTask(Task merchTask, string[] items)
    {
        short CompanyID = Convert.ToInt16((gSessions.GetSessionValue(gSessionsData.Company) as Company).ID);
        try
        { 
            merchTask.CompanyID = CompanyID; 
            if (merchTask.TaskID != 0)
            {
                taskTemplatesBF.Update(merchTask);
            }
            else
            {
                taskTemplatesBF.InsertMerchTask(merchTask);
            } 
            string[] selectedLst = items;
            foreach (string item in selectedLst)
            { 
                taskTemplatesBF.InsertItemsLink(CompanyID,merchTask.TaskID,merchTask.ItemCode);
            } 
        }
        catch (Exception ex)
        {
            if (ex.InnerException != null)
            {
                ModelState.AddModelError("", ex.InnerException.Message);
            }
            ModelState.AddModelError("", ex.Message);
        }
    return RedirectToAction("TasksTemplates", "Merch");

}

*I found a workaround to send each object separately in different ajax but what's wrong when I send them in one request?

Laravel 5.8 Ajax CRUD tutorial using Datatable JS

Laravel 5.8 Ajax CRUD tutorial using Datatable JS

In this tutorial, i want to share with you create jquery ajax crud operations application using datatable js, modals in laravel 5.8. we will create insert update delete records with modal and pagination in laravel 5.8.

In this tutorial, i want to share with you create jquery ajax crud operations application using datatable js, modals in laravel 5.8. we will create insert update delete records with modal and pagination in laravel 5.8.

We will use yajra datatable to list a records with pagination, sorting and filter (search). we will use bootstrap modal for create new records and update new records. we will use resource routes to create crud (create read update delete) application in laravel 5.8.

I will provide you step by step guide to create ajax crud example with laravel 5.8. you just need to follow few step to get c.r.u.d with modals and ajax. you can easily use with your laravel 5.8 project and easy to customize it.

You can see bellow preview of ajax crud app.

List Page

Create Page

Edit Page

Step 1 : Install Laravel 5.8

first of all we need to get fresh Laravel 5.8 version application using bellow command, So open your terminal OR command prompt and run bellow command:

composer create-project --prefer-dist laravel/laravel blog

Step 2 : Install Yajra Datatable Package

We need to install yajra datatable composer package for datatable, so you can install using following command:

composer require yajra/laravel-datatables-oracle

After that you need to set providers and alias.

config/app.php

'providers' => [

	....

	Yajra\DataTables\DataTablesServiceProvider::class,

]

'aliases' => [

	....

	'DataTables' => Yajra\DataTables\Facades\DataTables::class,

]

Step 3: Update Database Configuration

In second step, we will make database configuration for example database name, username, password etc for our crud application of laravel 5.8. So let’s open .env file and fill all details like as bellow:

.env

DB_CONNECTION=mysql

DB_HOST=127.0.0.1

DB_PORT=3306

DB_DATABASE=here your database name(blog)

DB_USERNAME=here database username(root)

DB_PASSWORD=here database password(root)

Step 4: Create Table

we are going to create ajax crud application for product. so we have to create migration for “products” table using Laravel 5.8 php artisan command, so first fire bellow command:

php artisan make:migration create_products_table --create=products

After this command you will find one file in following path “database/migrations” and you have to put bellow code in your migration file for create products table.

<?php

 

use Illuminate\Support\Facades\Schema;

use Illuminate\Database\Schema\Blueprint;

use Illuminate\Database\Migrations\Migration;

  

class CreateProductsTable extends Migration

{

    /**

     * Run the migrations.

     *

     * @return void

     */

    public function up()

    {

        Schema::create('products', function (Blueprint $table) {

            $table->increments('id');

            $table->string('name');

            $table->text('detail');

            $table->timestamps();

        });

    }

  

    /**

     * Reverse the migrations.

     *

     * @return void

     */

    public function down()

    {

        Schema::dropIfExists('products');

    }

}

Now you have to run this migration by following command:

php artisan migrate

Step 5: Create Resource Route

Here, we need to add resource route for product ajax crud application. so open your “routes/web.php” file and add following route.

routes/web.php

Route::resource('ajaxproducts','ProductAjaxController');

Step 6: Create Controller and Model

In this step, now we should create new controller as ProductAjaxController. So run bellow command and create new controller.

So, let’s copy bellow code and put on ProductAjaxController.php file.

app/Http/Controllers/ProductAjaxController.php

<?php

         

namespace App\Http\Controllers;

          

use App\Product;

use Illuminate\Http\Request;

use DataTables;

        

class ProductAjaxController extends Controller

{

    /**

     * Display a listing of the resource.

     *

     * @return \Illuminate\Http\Response

     */

    public function index(Request $request)

    {

   

        if ($request->ajax()) {

            $data = Product::latest()->get();

            return Datatables::of($data)

                    ->addIndexColumn()

                    ->addColumn('action', function($row){

   

                           $btn = '<a href="javascript:void(0)" data-toggle="tooltip"  data-id="'.$row->id.'" data-original-title="Edit" class="edit btn btn-primary btn-sm editProduct">Edit</a>';

   

                           $btn = $btn.' <a href="javascript:void(0)" data-toggle="tooltip"  data-id="'.$row->id.'" data-original-title="Delete" class="btn btn-danger btn-sm deleteProduct">Delete</a>';

    

                            return $btn;

                    })

                    ->rawColumns(['action'])

                    ->make(true);

        }

      

        return view('productAjax',compact('products'));

    }

     

    /**

     * Store a newly created resource in storage.

     *

     * @param  \Illuminate\Http\Request  $request

     * @return \Illuminate\Http\Response

     */

    public function store(Request $request)

    {

        Product::updateOrCreate(['id' => $request->product_id],

                ['name' => $request->name, 'detail' => $request->detail]);        

   

        return response()->json(['success'=>'Product saved successfully.']);

    }

    /**

     * Show the form for editing the specified resource.

     *

     * @param  \App\Product  $product

     * @return \Illuminate\Http\Response

     */

    public function edit($id)

    {

        $product = Product::find($id);

        return response()->json($product);

    }

  

    /**

     * Remove the specified resource from storage.

     *

     * @param  \App\Product  $product

     * @return \Illuminate\Http\Response

     */

    public function destroy($id)

    {

        Product::find($id)->delete();

     

        return response()->json(['success'=>'Product deleted successfully.']);

    }

}

Ok, so after run bellow command you will find “app/Product.php” and put bellow content in Product.php file:

app/Product.php

<?php

  

namespace App;

  

use Illuminate\Database\Eloquent\Model;

   

class Product extends Model

{

    protected $fillable = [

        'name', 'detail'

    ];

}

Step 7: Create Blade Files

In last step. In this step we have to create just blade file. so we need to create only one blade file as productAjax.blade.php file.

So let’s just create following file and put bellow code.

resources/views/productAjax.blade.php

<!DOCTYPE html>

<html>

<head>

    <title>Laravel 5.8 Ajax CRUD tutorial using Datatable - ItSolutionStuff.com</title>

    <meta name="csrf-token" content="{{ csrf_token() }}">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />

    <link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">

    <link href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css" rel="stylesheet">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>  

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>

    <script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>

    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>

    <script src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>

</head>

<body>

    

<div class="container">

    <h1>Laravel 5.8 Ajax CRUD tutorial using Datatable - ItSolutionStuff.com</h1>

    <a class="btn btn-success" href="javascript:void(0)" id="createNewProduct"> Create New Product</a>

    <table class="table table-bordered data-table">

        <thead>

            <tr>

                <th>No</th>

                <th>Name</th>

                <th>Details</th>

                <th width="280px">Action</th>

            </tr>

        </thead>

        <tbody>

        </tbody>

    </table>

</div>

   

<div class="modal fade" id="ajaxModel" aria-hidden="true">

    <div class="modal-dialog">

        <div class="modal-content">

            <div class="modal-header">

                <h4 class="modal-title" id="modelHeading"></h4>

            </div>

            <div class="modal-body">

                <form id="productForm" name="productForm" class="form-horizontal">

                   <input type="hidden" name="product_id" id="product_id">

                    <div class="form-group">

                        <label for="name" class="col-sm-2 control-label">Name</label>

                        <div class="col-sm-12">

                            <input type="text" class="form-control" id="name" name="name" placeholder="Enter Name" value="" maxlength="50" required="">

                        </div>

                    </div>

     

                    <div class="form-group">

                        <label class="col-sm-2 control-label">Details</label>

                        <div class="col-sm-12">

                            <textarea id="detail" name="detail" required="" placeholder="Enter Details" class="form-control"></textarea>

                        </div>

                    </div>

      

                    <div class="col-sm-offset-2 col-sm-10">

                     <button type="submit" class="btn btn-primary" id="saveBtn" value="create">Save changes

                     </button>

                    </div>

                </form>

            </div>

        </div>

    </div>

</div>

    

</body>

    

<script type="text/javascript">

  $(function () {

     

      $.ajaxSetup({

          headers: {

              'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')

          }

    });

    

    var table = $('.data-table').DataTable({

        processing: true,

        serverSide: true,

        ajax: "{{ route('ajaxproducts.index') }}",

        columns: [

            {data: 'DT_RowIndex', name: 'DT_RowIndex'},

            {data: 'name', name: 'name'},

            {data: 'detail', name: 'detail'},

            {data: 'action', name: 'action', orderable: false, searchable: false},

        ]

    });

     

    $('#createNewProduct').click(function () {

        $('#saveBtn').val("create-product");

        $('#product_id').val('');

        $('#productForm').trigger("reset");

        $('#modelHeading').html("Create New Product");

        $('#ajaxModel').modal('show');

    });

    

    $('body').on('click', '.editProduct', function () {

      var product_id = $(this).data('id');

      $.get("{{ route('ajaxproducts.index') }}" +'/' + product_id +'/edit', function (data) {

          $('#modelHeading').html("Edit Product");

          $('#saveBtn').val("edit-user");

          $('#ajaxModel').modal('show');

          $('#product_id').val(data.id);

          $('#name').val(data.name);

          $('#detail').val(data.detail);

      })

   });

    

    $('#saveBtn').click(function (e) {

        e.preventDefault();

        $(this).html('Sending..');

    

        $.ajax({

          data: $('#productForm').serialize(),

          url: "{{ route('ajaxproducts.store') }}",

          type: "POST",

          dataType: 'json',

          success: function (data) {

     

              $('#productForm').trigger("reset");

              $('#ajaxModel').modal('hide');

              table.draw();

         

          },

          error: function (data) {

              console.log('Error:', data);

              $('#saveBtn').html('Save Changes');

          }

      });

    });

    

    $('body').on('click', '.deleteProduct', function () {

     

        var product_id = $(this).data("id");

        confirm("Are You sure want to delete !");

      

        $.ajax({

            type: "DELETE",

            url: "{{ route('ajaxproducts.store') }}"+'/'+product_id,

            success: function (data) {

                table.draw();

            },

            error: function (data) {

                console.log('Error:', data);

            }

        });

    });

     

  });

</script>

</html>

Now you can test it by using following command:

php artisan serve

Now you can open bellow URL on your browser:

http://localhost:8000/ajaxproducts

I hope it can help you…

Create Login and Registration in Your ASP.NET Core MVC App

Create Login and Registration in Your ASP.NET Core MVC App

This tutorial walks you through setting up login and registration with ASP.NET Core MVC. In this tutorial, you learned how to add authentication to your ASP.NET Core MVC app and allow users to register for a new account.

This tutorial walks you through setting up login and registration with ASP.NET Core MVC. In this tutorial, you learned how to add authentication to your ASP.NET Core MVC app and allow users to register for a new account.

User authentication and authorization are common features in web applications, but building these mechanics has the potential to take a lot of time. Doing so requires setting up persistent storage for user information (in some type of database) and paying keen attention to potential security issues around sensitive operations like hashing passwords, password reset workflows, etc. - weeks of development time begin to add up before we ever get to the functionality that delivers value to your users.

In this post, we’ll walk through how Okta simplifies this process for us and set up a simple integration for an ASP.NET Core MVC app using the Okta NuGet package. We’ll build functionality for users to register for new accounts and login with their Okta credentials.

Scaffold Your ASP.NET Project

To follow along with this tutorial start by creating a new app in the console:

mkdir MyOktaProject
cd MyOktaProject
dotnet new mvc


Configure User Registration

If you don’t already have one, you’ll need to create an Okta developer account. Doing so will give you a URL for your organization called an “Okta domain”. It will also allow you to create your login credentials for accessing the Okta dashboard.

Upon submission of this form, you will receive an email Okta with instructions to obtain your credentials and complete your registration.

Execute the following steps to configure Okta so that users can register themselves for an account.

  1. From the Administrative Dashboard, hover over Users and click Registration
  2. Click Enable Registration
  3. Save the changes

Configure Basic User Authentication

Once you have access to your account you can proceed to the Dashboard using a link like the one below:

<span

class="okta-preview-domain">https://{yourOktaDomain}/admin/dashboard

On the Dashboard, click Applications in the main menu and on the Application screen, click Add Application.

Select Web then click Next.

On the Create New Application screen, set the following values:

Click Done, then click Edit next to General Settings on your newly created Okta app. Edit the following values:

Logout redirect URIs: https://localhost:5001/signout-callback-oidc

Initiate login URI: https://localhost:5001/authorization-code/callback

Add .NET Authentication Dependencies

Once your account is set up you need to add the Okta.Sdk library to your project. This post will take the approach of using the NuGet package, but the Github repository for Okta.AspNetCore can be found here.

To proceed simply search for the latest version of the Okta.Sdk NuGet package in your IDE of choice (version 1.2.0 at the time of this publication) and install it. If you’re using Visual Studio you can do this by right-clicking on the project in the solution explorer and selecting Manage NuGet Packages. For those of you not using Visual Studio, add the package via console window using the following command:

dotnet add package Okta.Sdk --version 1.2.0


Configure Your ASP.NET App for Login

Authentication works by redirecting users to the Okta website, where they will log in with their credentials, and then be returned to your site via the URL you configured above.

Add the following code to your appsettings.json file:

  "Okta": {
    "Issuer": "https://{yourOktaDomain}/oauth2/default",
    "ClientId": "{yourClientId}",
    "ClientSecret": "{yourClientSecret}"
  }


You can find each of the actual values needed to replace the settings in the config above in the following places:

ClientId refers to the client ID of the Okta application ClientSecret refers to the client secret of the Okta application Issuer will need the text {yourOktaDomain} replaced with your Okta domain, found at the top-right of the Dashboard page

Add some using statements to your Startup.cs file:

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;


Add the following code to the top of the ConfigureServices method in your Startup.cs file:

services.AddAuthentication(sharedOptions =>
{
    sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
    .AddCookie()
    .AddOpenIdConnect(options =>
    {
        options.ClientId = Configuration["okta:ClientId"];
        options.ClientSecret = Configuration["okta:ClientSecret"];
        options.Authority = Configuration["okta:Issuer"];
        options.CallbackPath = "/authorization-code/callback";
        options.ResponseType = "code";
        options.SaveTokens = true;
        options.UseTokenLifetime = false;
        options.GetClaimsFromUserInfoEndpoint = true;
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = "name"
        };
    });


In the Configure() method of your Startup.cs file add this line just before the app.UseMvc() method:

app.UseAuthentication();


Add the following MeViewModel to the Models directory:

using System.Collections.Generic;

namespace OktaAspNetCoreMvc.Models
{
    public class MeViewModel
    {
        public string Username { get; set; }

        public bool SdkAvailable { get; set; }

        public dynamic UserInfo { get; set; }

        public IEnumerable<string> Groups { get; set; }
    }
}


Add Login to Your ASP.NET App

Now that all the configuration and plumbing is done, you’re ready to add the code that will actually log users into your application.

Add the following AccountController to the Controller directory.

The controller exposes the Login() action. If the user has already been authenticated, the Login() action will redirect them to the home page. Otherwise, it will redirect them to the Okta login screen.

using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Mvc;
using Okta.Sdk;

namespace OktaAspNetCoreMvc.Controllers
{
    public class AccountController : Controller
    {
        private readonly IOktaClient _oktaClient;

        public AccountController(IOktaClient oktaClient = null)
        {
            _oktaClient = oktaClient;
        }

        public IActionResult Login()
        {
            if (!HttpContext.User.Identity.IsAuthenticated)
            {
                return Challenge(OpenIdConnectDefaults.AuthenticationScheme);
            }

            return RedirectToAction("Index", "Home");
        }
    }
}


Add the following code to your _Layout.cshtml file, just below the main menu to add the login button, or a welcome message, based on the current user’s status.:

   @if (User.Identity.IsAuthenticated)
    {
        <ul class="nav navbar-nav navbar-right">
            <li><p class="navbar-text">Hello, @User.Identity.Name</p></li>
        </ul>
    }
    else
    {
        <ul class="nav navbar-nav navbar-right">
            <li><a asp-controller="Account" asp-action="Login">Log in</a></li>
        </ul>
    }


For information on user authorization using Okta groups check out Lee Brandt’s article on user authorization in ASP.NET Core with Okta.

Register Users

If you following the instructions above to enable self-service registration the “Don’t have an account? Sign Up” message will appear at the bottom of the login form. In the next step, you’ll run the application.

Log In Using ASP.NET

That’s it! To run your solution open up a terminal and enter the following command:

dotnet run


Then navigate to http://localhost:5001 in your browser and enjoy!

The source code for this tutorial is available on GitHub.

Now you have a website with a working login and user registration form. Your website also allows users to recover lost passwords. By repeating these steps you can create a network of tools that your users can access all with the same login.

Learn More

The Complete ASP.NET MVC 5 Course

Build a Real-world App with ASP.NET Core and Angular 2 (4+)

ASP NET Core (ASP.NET 5),MVC 6,C#,Angular2 & EF Crash Course

Rest Api’s in Asp.Net and C#

Hands on ASP .Net Core 2

Laravel 5.8 Tutorial - Datatables Dropdown Filter Server-side using Ajax

Laravel 5.8 Tutorial - Datatables Dropdown Filter Server-side using Ajax

In this post, we will learn how to Search or Filter Laravel Datatables data using Ajax jQuery with Individual column searching. Here you can find a complete process of Individual column searching with server side process in Laravel data tables using yajra from scratch.

Originally published at https://www.webslesson.info

This is one more post on Laravel 5.8 with Datatables and in this post we will cover How can we implement Laravel Datatables Individual Column Searching using Ajax. In some of our previous post, we have already covered topic like how to add custom search filter in Laravel Datatables and How to make Daterange search filter in Laravel Datatables. Now here we have come with new topic in Laravel 5.8 framework with Datatables and here we will show you how to add Individual column dropdown search filter in Laravel DataTables.

Here we will create dropdown search filter in Laravel DataTables with serve-side processing of data that means all searching or filtering of data will be process at server side and display result on web page without refresh of web page because here we will use Ajax with Laravel 5.8 and Datatables. For implement DataTables with Laravel 5.8 here we will use yajra/laravel-datatables-oracle package. By using this package we can use jQuery DataTables in Laravel 5.8 framework.

For learn individual column searching or filtering of DataTables data, we will add dropdown list in one of the column of DataTables and then after by using jQuery and Ajax we will filter DataTables data. For this here we will take and example of display product data on DataTables, now we want to filter this product data based on category of product. So, we will make category dropdown list in category column, and based on value of category we will filter or search product data in DataTables with Laravel 5.8 using Ajax jQuery. Below you can find step by step process for Laravel 5.8 DataTables Individual column searching or filtering of data using Ajax jquery.

  • Make Tables in Mysql Database
  • Install Laravel 5.8 framework
  • Install yajra/laravel-datatables-oracle package
  • Make Database connection in Laravel 5.8
  • Create Controllers in Laravel 5.8 application
  • Create Blade view file in Laravel 5.8
  • Set Route of Controllers method
  • Run Laravel 5.8 Application

Make Tables in Mysql Database

First you have make table in your mysql database, for this you have to run following sql script in your mysql database. It will make category table and product table in your database. Here we will fetch data from this two table by join table with category_id primary key in category table and category foreign key in product table.

--
-- Database: testing1

--
-- Table structure for table category

CREATE TABLE IF NOT EXISTS category (
 category_id int(11) NOT NULL,
 category_name varchar(250) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;

--
-- Dumping data for table category

INSERT INTO category (category_id, category_name) VALUES
(1, 'Mobiles'),
(2, 'Computers'),
(3, 'Clothing'),
(4, 'Beauty Item'),
(5, 'Sports Item'),
(6, 'Toys Item'),
(7, 'Books'),
(8, 'Entertainment Item');


--
-- Table structure for table product

CREATE TABLE IF NOT EXISTS product (
 id int(11) NOT NULL,
 category int(11) NOT NULL,
 name varchar(250) NOT NULL,
 price double(10,2) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=latin1;

--
-- Dumping data for table product

INSERT INTO product (id, category, name, price) VALUES
(1, 1, 'Save on BLU Advance 5.5 HD', 74.99),
(2, 2, 'Dell Inspiron 15.6" Gaming Laptop', 860.00),
(3, 3, 'Women''s Slim Sleeveless', 69.00),
(4, 4, 'Andis 1875-Watt Fold-N-Go Ionic Hair Dryer', 17.00),
(5, 5, 'GM Ripple Cricket Grip, Set Of 3', 66.00),
(6, 6, 'Barbie Fashions and Accessories', 12.00),
(7, 7, 'The Ministry of Utmost Happiness', 6.00),
(8, 8, 'The Great Gatsby (3D)', 8.00),
(9, 1, 'iVooMi Me 1+', 49.00),
(10, 2, 'Apple MacBook Air MQD32HN/A 13.3-inch Laptop 2017', 896.00),
(11, 3, 'Balenzia Premium Mercerised Cotton Loafer Socks', 5.00),
(12, 4, 'Organix Mantra Lemon Cold Pressed Essential Oil', 4.50),
(13, 5, 'SpeedArm Cricket Ball Thrower', 15.00),
(14, 6, 'Mattel Bounce Off Game, Multi Color', 10.00),
(15, 7, 'Seven Days With Her Boss', 5.00),
(16, 8, 'Supernatural Season 1-9 DVD', 22.00),
(17, 1, 'InFocus Turbo 5', 189.00),
(18, 2, 'HP 15-bg008AU 15.6-inch Laptop , Jack Black', 350.00),
(19, 3, 'Seven Rocks Men''s V-Neck Cotton Tshirt', 12.00),
(20, 4, 'Exel Elixir Sublime Antioxidant Serum Cream', 55.00),
(21, 5, 'Gray Nicolls Bat Repair Kit', 9.00),
(22, 6, 'Think Fun Rush Hour, Multi Color', 22.00),
(23, 7, 'Pregnancy Notes: Before, During & After', 5.00),
(24, 8, 'Sherlock Season - 4', 15.00),
(25, 1, 'Vivo Y53', 105.00),
(26, 2, 'Dell Inspiron 15-3567 15.6-inch Laptop', 356.00),
(27, 3, 'Fastrack Sport Sunglasses (Black) (P222GR1)', 14.00),
(28, 4, 'Exel Lotion with stabilized Tea Tree Oil', 28.00),
(29, 5, 'Burn Vinyl Hexagonal Dumbbell', 45.00),
(30, 6, 'Cup Cake Surprise Princess', 8.00),
(31, 7, 'Word Power Made Easy', 2.00),
(32, 8, 'Star Wars: The Force Awakens', 5.00),
(33, 1, 'Lenovo Vibe K5 (Gold, VoLTE update)', 65.00),
(34, 2, 'Lenovo 110 -15ACL 15.6-inch Laptop , Black', 225.00),
(35, 3, 'Zacharias Ankle Socks Pack of 12 Pair', 5.00),
(36, 4, 'Exel SUNSCREEN Broad Spectrum UVA & UVB', 26.00),
(37, 5, 'Burn 500124 Inter Lock Mat (Black)', 24.00),
(38, 6, 'Toyshine Devis Boy 9', 10.00),
(39, 7, 'Think and Grow Rich', 2.50),
(40, 8, 'The Jungle Book', 10.00);

--
-- Indexes for dumped tables --
-- Indexes for table category

ALTER TABLE category
 ADD PRIMARY KEY (category_id);

--
-- Indexes for table product

ALTER TABLE product
 ADD PRIMARY KEY (id);

--
-- AUTO_INCREMENT for dumped tables --
-- AUTO_INCREMENT for table category ALTER TABLE category
 MODIFY category_id int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=9; -- AUTO_INCREMENT for table product

ALTER TABLE product
 MODIFY id int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=41;

Install Laravel 5.8 framework

Now we want to download and install Laravel 5.8 framework in our computer. For this we have to go command prompt in which first we want to run composer command because it has manage Laravel library dependancy and after this we have to write following command. This command will download and install Laravel 5.8 framework in your local computer.

composer create-project --prefer-dist laravel/laravel column_searching
Install yajra/laravel-datatables-oracle package

Here we want to use DataTables with Laravel. For this use DataTables with Laravel we want to download and install yajra laravel datatables package. By using this package we can use DataTables in Laravel framework. For this we have to go command prompt and write following command.

composer require yajra/laravel-datatables-oracle

This command will download yajra laravel datatables package, now we want to publish this package in Laravel application. For this we have to go config/app.php and in this file we have to define autoload service providers and aliase class details.

'providers' => [

       ............

       Yajra\Datatables\DatatablesServiceProvider::class,

   ],

   'aliases' => [
       
        ............
      
        'Datatables' => Yajra\Datatables\Facades\Datatables::class,

   ],

Make Database connection in Laravel 5.8

After this we want to make database connection in this Laravel 5.8 application, for this we have to open .env file and in this we have to define Mysql database configuration.


........................

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=testing
DB_USERNAME=root
DB_PASSWORD=

........................

Create Controllers in Laravel 5.8 application

Now we want to make controllers in Laravel 5.8 application for handle http request. For this we have to go command prompt and write following command.

php artisan make:controller ColumnSearchingController

This command will create ColumnSearchingController.php controller class in app/Http/Controllers folder. In this class first we have write use DB; statement. By using this statement we can perform database related operation. In this class we have make following method.

index(Request $request) - This the root method of this class. This method has load column_searching.blade.php file in browser with the category data for fill category dropdown list box for filter data. This method has also received ajax request for load all data in Datatable or load filter data in Datatable. This method has also send data from datatables also.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use DB;

class ColumnSearchingController extends Controller
{
   function index(Request $request)
   {
    if(request()->ajax())
    {
     if($request->category)
     {
      $data = DB::table('product')
        ->join('category', 'category.category_id', '=', 'product.category')
        ->select('product.id', 'product.name', 'category.category_name', 'product.price')
        ->where('product.category', $request->category);
     }
     else
     {
      $data = DB::table('product')
        ->join('category', 'category.category_id', '=', 'product.category')
        ->select('product.id', 'product.name', 'category.category_name', 'product.price');
     }

     return datatables()->of($data)->make(true);
    }

    $category = DB::table('category')
       ->select("*")
       ->get();

    return view('column_searching', compact('category'));
   }
}

?>

Create Blade view file in Laravel 5.8

View file is mainly used for display html output data on web page. In laravel we have store view file in resources/views/column_searching.blade.php. In this blade view file we have already imported required library like jQuery, Bootstrap and jquery DataTables. Here first it has make category dropdown list box by using category data from controller index method. In this page we have also write jquery and Ajax code for initialize jQuery DataTables plugin and dropdown search filter of DataTables data also.

<html>
<head>
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <title>Laravel 5.8 Tutorial - Datatables Individual Column Searching using Ajax</title>
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
 <script src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script>
 <script src="https://cdn.datatables.net/1.10.12/js/dataTables.bootstrap.min.js"></script> 
  <link rel="stylesheet" href="https://cdn.datatables.net/1.10.12/css/dataTables.bootstrap.min.css" />
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
 <div class="container">   
     <br />
    <h3 align="center">Laravel 5.8 Tutorial - Datatables Individual Column Searching using Ajax</h3>
    <br />
  <div class="table-responsive">
   <table class="table table-bordered table-striped" id="product_table">
    <thead>
     <tr>
      <th>Sr. No.</th>
      <th>Product Name</th>
      <th>
       <select name="category_filter" id="category_filter" class="form-control">
        <option value="">Select Category</option>
        @foreach($category as $row)
        <option value="{{ $row->category_id }}">{{ $row->category_name }}</option>
        @endforeach
       </select>
      </th>
      <th>Product Price</th>
     </tr>
    </thead>
   </table>
  </div>
  <br />
  <br />
 </div>
</body>
</html>

<script>
$(document).ready(function(){
 
fetch_data();
 
function fetch_data(category = '')
{
  $('#product_table').DataTable({
   processing: true,
   serverSide: true,
   ajax: {
    url:"{{ route('column-searching.index') }}",
    data: {category:category}
   },
   columns:[
    {
     data: 'id',
     name: 'id'
    },
    {
     data: 'name',
     name: 'name'
    },
    {
     data: 'category_name',
     name: 'category_name',
     orderable: false
    },
    {
     data:'price',
     name:'price'
    }
   ]
  });
}
 
$('#category_filter').change(function(){
  var category_id = $('#category_filter').val();
 
  $('#product_table').DataTable().destroy();
 
  fetch_data(category_id);
});

});
</script>

Set Route of Controllers method

Once all code is ready, now we want to set route of controller method. For this we have to go routes/web.php file and under this file we have to define route for controller method.

<?php

Route::resource('column-searching', 'ColumnSearchingController');

?>

Run Laravel 5.8 Application

Lastly, we want to run Laravel 5.8 application. For this again we want to go command prompt and write following command.

php artisan serve

This command will start Laravel 5.8 application and give base url of your application. For run above code, we have to write http://127.0.0.1:8000/column-searching. It will execute above code. So this is complete step by step process of server side processing of Individual Datatables column searching or filtering of Data in Laravel 5.8 using Ajax. So, test this script and learn something new in Laravel framework.


How to build RESTful APIs with ASP.NET Core

How to build RESTful APIs with ASP.NET Core

A step by step guide on how to implement clean, maintainable RESTful APIs

A step by step guide on how to implement clean, maintainable RESTful APIs

Overview

RESTful is not a new term. It refers to an architectural style where web services receive and send data from and to client apps. The goal of these applications is to centralize data that different client apps will use.

Choosing the right tools to write RESTful services is crucial since we need to care about scalability, maintenance, documentation, and all other relevant aspects. The ASP.NET Core gives us a powerful, easy to use API that is great to achieve these goals.

In this article, I’ll show you how to write a well structured RESTful API for an “almost” real world scenario, using the ASP.NET Core framework. I’m going to detail common patterns and strategies to simplify the development process.

I’ll also show you how to integrate common frameworks and libraries, such as Entity Framework Core and AutoMapper, to deliver the necessary functionalities.

Prerequisites

I expect you to have knowledge of object-oriented programming concepts.

Even though I’m going to cover many details of the C# programming language, I recommend you to have basic knowledge of this subject.

I also assume you know what REST is, how the HTTP protocol works, what are API endpoints and what is JSON. Here is a great introductory tutorial on this subject. The final requirement is that you understand how relational databases work.

To code along with me, you will have to install the .NET Core 2.2, as well as Postman, the tool I’m going to use to test the API. I recommend you to use a code editor such as Visual Studio Code to develop the API. Choose the code editor you prefer. If you choose this code editor, I recommend you to install the C# extension to have better code highlighting.

You can find a link to the Github repository of the API at the end of this article, to check the final result.

The Scope

Let’s write a fictional web API for a supermarket. Let’s imagine we have to implement the following scope:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

To simplify the example, I won’t handle products in stock, product shipping, security and any other functionality. The given scope is enough to show you how ASP.NET Core works.

To develop this service, we basically need two API endpoints: one to manage categories and one to manage products. In terms of JSON communication, we can think of responses as follow:

API endpoint: /api/categories

JSON Response (for GET requests):

{

  [

    { "id": 1, "name": "Fruits and Vegetables" },

    { "id": 2, "name": "Breads" },

    … // Other categories

  ]

}

API endpoint: /api/products

JSON Response (for GET requests):

{

  [

    {

      “id”: 1,

      “name”: “Sugar”,

      “quantityInPackage”: 1,

      “unitOfMeasurement”: “KG”

      “category”: {

        “id”: 3,

        “name”: “Sugar”

      }

    },

    … // Other products

  ]

}

Let’s get started writing the application.

Step 1 — Creating the API

First of all, we have to create the folders structure for the web service, and then we have to use the .NET CLI tools to scaffold a basic web API. Open the terminal or command prompt (it depends on the operating system you are using) and type the following commands, in sequence:

mkdir src/Supermarket.API

cd src/Supermarket.API

dotnet new webapi

The first two commands simply create a new directory for the API and change the current location to the new folder. The last one generates a new project following the Web API template, that is the kind of application we’re developing. You can read more about these command and other project templates you can generate checking this link.

The new directory now will have the following structure:

Structure Overview

An ASP.NET Core application consists of a group of middlewares (small pieces of the application attached to the application pipeline, that handle requests and responses) configured in the Startup class. If you’ve already worked with frameworks like Express.js before, this concept isn’t new to you.

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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    // 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();
        }
        else
        {
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

When the application starts, the Mainmethod, from the Program class, is called. It creates a default web host using the startup configuration, exposing the application via HTTP through a specific port (by default, port 5000 for HTTP and 5001 for HTTPS).

namespace Supermarket.API
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }
}

Take a look at the ValuesController class inside the Controllers folder. It exposes methods that will be called when the API receives requests through the route /api/values.

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5
    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
        return "value";
    }

    // POST api/values
    [HttpPost]
    public void Post([FromBody] string value)
    { 
    }

    // PUT api/values/5
    [HttpPut("{id}")]
    public void Put(int id, [FromBody] string value)
    {   
    }

    // DELETE api/values/5
    [HttpDelete("{id}")]
    public void Delete(int id)
    {  
    }
}

Don’t worry if you don’t understand some part of this code. I’m going to detail each one when developing the necessary API endpoints. For now, simply delete this class, since we’re not going to use it.

Step 2 — Creating the Domain Models

I’m going to apply some design concepts that will keep the application simple and easy to maintain.

Writing code that can be understood and maintained by yourself is not this difficult, but you have to keep in mind that you’ll work as part of a team. If you don’t take care on how you write your code, the result will be a monster that will give you and your teammates constant headaches. It sounds extreme, right? But believe me, that’s the truth.

Let’s start by writing the domain layer. This layer will have our models classes, the classes that will represent our products and categories, as well as repositories and services interfaces. I’ll explain these last two concepts in a while.

Inside the Supermarket.API directory, create a new folder called Domain. Within the new domain folder, create another one called Models. The first model we have to add to this folder is the Category. Initially, it will be a simple Plain Old CLR Object (POCO) class. It means the class will have only properties to describe its basic information.

using System.Collections.Generic;

namespace Supermarket.API.Domain.Models
{
    public class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public IList<Product> Products { get; set; } = new List<Product>();
    }
}

The class has an Idproperty, to identify the category, and a Nameproperty. We also have a Productsproperty. This last one will be used by Entity Framework Core, the ORM most ASP.NET Core applications use to persist data into a database, to map the relationship between categories and products. It also makes sense thinking in terms of object-oriented programming, since a category has many related products.

We also have to create the product model. At the same folder, add a new Product class.

namespace Supermarket.API.Domain.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public short QuantityInPackage { get; set; }
        public EUnitOfMeasurement UnitOfMeasurement { get; set; }

        public int CategoryId { get; set; }
        public Category Category { get; set; }
    }
}

The product also has properties for the Id and name. The is also a property QuantityInPackage, that tells how many units of the product we have in one pack (remember the biscuits example of the application scope) and a UnitOfMeasurementproperty. This one is represented by an enum type, that represents an enumeration of possible units of measurement. The last two properties, CategoryIdand Category will be used by the ORM to map the relationship between products and categories. It indicates that a product has one, and only one, category.

Let’s define the last part of our domain models, the EUnitOfMeasurementenum. By convention, enums in C# should start with an “E” in front of their names.

using System.ComponentModel;

namespace Supermarket.API.Domain.Models
{
    public enum EUnitOfMeasurement : byte
    {
        [Description("UN")]
        Unity = 1,

        [Description("MG")]
        Milligram = 2,

        [Description("G")]
        Gram = 3,

        [Description("KG")]
        Kilogram = 4,

        [Description("L")]
        Liter = 5
    }
}

The code is really straightforward. Here we defined only a handful of possibilities for units of measurement, however, in a real supermarket system, you may have many other units of measurement, and maybe a separate model for that.

Notice the Descriptionattribute applied over every enumeration possibility. An attribute is a way to define metadata over classes, interfaces, properties and other components of the C# language. In this case, we’ll use it to simplify the responses of the products API endpoint, but you don’t have to care about it for now. We’ll come back here later.

Our basic models are ready to be used. Now we can start writing the API endpoint that is going to manage all categories.

Step 3 — The Categories API

In the Controllers folder, add a new class called CategoriesController.

By convention, all classes in this folder that end with the suffix “Controller” will become controllers of our application. It means they are going to handle requests and responses. You have to inherit this class from the Controller class, defined in the namespace Microsoft.AspNetCore.Mvc.

A namespace consists of a group of related classes, interfaces, enums, and structs. You can think of it as something similar to modules of the Javascript language, or packages from Java.

The new controller should respond through the route /api/categories. We achieve this by adding the Routeattribute above the class name, specifying a placeholder that indicates that the route should use the class name without the controller suffix, by convention.

using Microsoft.AspNetCore.Mvc;

namespace Supermarket.API.Controllers
{
    [Route("/api/[controller]")]
    public class CategoriesController : Controller
    {
    }
}

Let’s start handling GET requests. First of all, when someone requests data from /api/categories via GET verb, the API needs to return all categories. We can create a category service for this purpose.

Conceptually, a service is basically a class or interface that defines methods to handle some business logic. It is a common practice in many different programming languages to create services to handle business logic, such as authentication and authorization, payments, complex data flows, caching and tasks that require some interaction between other services or models.

Using services, we can isolate the request and response handling from the real logic needed to complete tasks.

The service we’re going to create initially will define a single behavior**,** or method: a listing method. We expect that this method returns all existing categories in the database.

For simplicity, we won’t deal with data pagination or filtering in this case. I’ll write an article in the future showing how to easily handle these features.

To define an expected behavior for something in C# (and in other object-oriented languages, such as Java, for example), we define an interface. An interface tells how something should work, but does not implement the real logic for the behavior. The logic is implemented in classes that implement the interface. If this concept isn’t clear for you, don’t worry. You’ll understand it in a while.

Within the Domain folder, create a new directory called Services. There, add an interface called ICategoryService. By convention, all interfaces should start with the capital letter_“I”_ in C#. Define the interface code as follows:

using System.Collections.Generic;
using System.Threading.Tasks;
using Supermarket.API.Domain.Models;

namespace Supermarket.API.Domain.Services
{
    public interface ICategoryService
    {
         Task<IEnumerable<Category>> ListAsync();
    }
}

The implementations of the ListAsync method must asynchronously return an enumeration of categories.

The Task class, encapsulating the return, indicates asynchrony. We need to think in an asynchronous method due to the fact that we have to wait for the database to complete some operation to return the data, and this process can take a while. Notice also the “async” suffix. It’s a convention that indicates that our method should be executed asynchronously.

We have a lot of conventions, right? I personally like it, because it keeps applications easy to read, even if you’re new to a company that uses .NET technology.

“ - Ok, we defined this interface, but it does nothing. How can it be useful?”

If you come from a language such as Javascript or another non-strongly typed language, this concept may seem strange.

Interfaces allow us to abstract the desired behavior from the real implementation. Using a mechanism known as dependency injection, we can implement these interfaces and isolate them from other components.

Basically, when you use dependency injection, you define some behaviors using an interface. Then, you create a class that implements the interface. Finally, you bind the references from the interface to the class you created.

“ - It sounds really confusing. Can’t we simply create a class that does these things for us?”

Let’s continue implementing our API and you will understand why to use this approach.

Change the CategoriesController code as follows:

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Supermarket.API.Domain.Models;
using Supermarket.API.Domain.Services;

namespace Supermarket.API.Controllers
{
    [Route("/api/[controller]")]
    public class CategoriesController : Controller
    {
        private readonly ICategoryService _categoryService;
        
        public CategoriesController(ICategoryService categoryService)
        {
            this._categoryService = categoryService;   
        }

        [HttpGet]
        public async Task<IEnumerable<Category>> GetAllAsync()
        {
            var categories = await _categoryService.ListAsync();
            return categories;
        }
    }
}

I have defined a constructor function for our controller (a constructor is called when a new instance of a class is created), and it receives an instance of ICategoryService. It means the instance can be anything that implements the service interface. I store this instance in a private, read-only field _categoryService. We’ll use this field to access the methods of our category service implementation.

By the way, the underscore prefix is another common convention to denote a field. This convention, in special, is not recommended by the official naming convention guideline of .NET, but it is a very common practice as a way to avoid having to use the “this” keyword to distinguish class fields from local variables. I personally think it’s much cleaner to read, and a lot of frameworks and libraries use this convention.

Below the constructor, I defined the method that is going to handle requests for /api/categories. The HttpGetattribute tells the ASP.NET Core pipeline to use it to handle GET requests (this attribute can be omitted, but it’s better to write it for easier legibility).

The method uses our category service instance to list all categories and then returns the categories to the client. The framework pipeline handles the serialization of data to a JSON object. The IEnumerable<Category>type tells the framework that we want to return an enumeration of categories, and the Task type, preceded by the async keyword, tells the pipeline that this method should be executed asynchronously. Finally, when we define an async method, we have to use the await keyword for tasks that can take a while.

Ok, we defined the initial structure of our API. Now, it is necessary to really implement the categories service.

Step 4 — Implementing the Categories Service

In the root folder of the API (the Supermarket.API folder), create a new one called Services. Here we’ll put all services implementations. Inside the new folder, add a new class called CategoryService. Change the code as follows:

using System.Collections.Generic;
using System.Threading.Tasks;
using Supermarket.API.Domain.Models;
using Supermarket.API.Domain.Services;

namespace Supermarket.API.Services
{
    public class CategoryService : ICategoryService
    {
        public async Task<IEnumerable<Category>> ListAsync()
        {
        }
    }
}

It’s simply the basic code for the interface implementation, but we still don’t handle any logic. Let’s think in how the listing method should work.

We need to access the database and return all categories, then we need to return this data to the client.

A service class is not a class that should handle data access. There is a pattern called Repository Pattern that is used to manage data from databases.

When using the Repository Pattern, we define repository classes, that basically encapsulate all logic to handle data access. These repositories expose methods to list, create, edit and delete objects of a given model, the same way you can manipulate collections. Internally, these methods talk to the database to perform CRUD operations, isolating the database access from the rest of the application.

Our service needs to talk to a category repository, to get the list of objects.

Conceptually, a service can “talk” to one or more repositories or other services to perform operations.

It may seem redundant to create a new definition for handling the data access logic, but you will see in a while that isolating this logic from the service class is really advantageous.

Let’s create a repository that will be responsible for intermediating the database communication as a way to persist categories.

Step 5 — The Categories Repository and the Persistence Layer

Inside the Domain folder, create a new directory called Repositories. Then, add a new interface called ICategoryRespository. Define the interface as follow:

https://gist.github.com/evgomes/a9263b0e596e02509e783c32f9fc5469.js

The initial code is basically identical to the code of the service interface.

Having defined the interface, we can come back to the service class and finish implementing the listing method, using an instance of ICategoryRepository to return the data.

using System.Collections.Generic;
using System.Threading.Tasks;
using Supermarket.API.Domain.Models;
using Supermarket.API.Domain.Repositories;
using Supermarket.API.Domain.Services;

namespace Supermarket.API.Services
{
    public class CategoryService : ICategoryService
    {
        private readonly ICategoryRepository _categoryRepository;

        public CategoryService(ICategoryRepository categoryRepository)
        {
            this._categoryRepository = categoryRepository;
        }

        public async Task<IEnumerable<Category>> ListAsync()
        { 
            return await _categoryRepository.ListAsync();
        }
    }
}

Now we have to implement the real logic of the category repository. Before doing it, we have to think about how we are going to access the database.

By the way, we still don’t have a database!

We’ll use the Entity Framework Core (I’ll call it EF Core for simplicity) as our database ORM. This framework comes with ASP.NET Core as its default ORM and exposes a friendly API that allows us to map classes of our applications to database tables.

The EF Core also allows us to design our application first, and then generate a database according to what we defined in our code. This technique is called code first. We’ll use the code first approach to generate a database (in this example, in fact, I’m going to use an in-memory database, but you will be able to easily change it to a SQL Server or MySQL server instance, for example).

In the root folder of the API, create a new directory called Persistence. This directory is going to have everything we need to access the database, such as repositories implementations.

Inside the new folder, create a new directory called Contexts, and then add a new class called AppDbContext. This class must inherit DbContext, a class EF Core uses to map your models to database tables. Change the code in the following way:

using Microsoft.EntityFrameworkCore;

namespace Supermarket.API.Domain.Persistence.Contexts
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
        {
        }
    }
}

The constructor we added to this class is responsible for passing the database configuration to the base class through dependency injection. You’ll see in a moment how this works.

Now, we have to create two DbSet properties. These properties aresets (collections of unique objects) that map models to database tables.

Also, we have to map the models’ properties to the respective table columns, specifying which properties are primary keys, which are foreign keys, the column types, etc. We can do this overriding the method OnModelCreating, using a feature called Fluent API to specify the database mapping. Change the AppDbContext class as follows:

using Microsoft.EntityFrameworkCore;
using Supermarket.API.Domain.Models;

namespace Supermarket.API.Persistence.Contexts
{
    public class AppDbContext : DbContext
    {
        public DbSet<Category> Categories { get; set; }
        public DbSet<Product> Products { get; set; }

        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
            
            builder.Entity<Category>().ToTable("Categories");
            builder.Entity<Category>().HasKey(p => p.Id);
            builder.Entity<Category>().Property(p => p.Id).IsRequired().ValueGeneratedOnAdd();
            builder.Entity<Category>().Property(p => p.Name).IsRequired().HasMaxLength(30);
            builder.Entity<Category>().HasMany(p => p.Products).WithOne(p => p.Category).HasForeignKey(p => p.CategoryId);

            builder.Entity<Category>().HasData
            (
                new Category { Id = 100, Name = "Fruits and Vegetables" }, // Id set manually due to in-memory provider
                new Category { Id = 101, Name = "Dairy" }
            );

            builder.Entity<Product>().ToTable("Products");
            builder.Entity<Product>().HasKey(p => p.Id);
            builder.Entity<Product>().Property(p => p.Id).IsRequired().ValueGeneratedOnAdd();
            builder.Entity<Product>().Property(p => p.Name).IsRequired().HasMaxLength(50);
            builder.Entity<Product>().Property(p => p.QuantityInPackage).IsRequired();
            builder.Entity<Product>().Property(p => p.UnitOfMeasurement).IsRequired();
        }
    }
}

The code is intuitive.

We specify to which tables our models should be mapped. Also, we set the primary keys, using the method HasKey, the table columns, using the Property method, and some constraints such as IsRequired, HasMaxLength, and ValueGeneratedOnAdd, everything with lambda expressions in a “fluent way” (chaining methods).

Take a look at the following piece of code:

builder.Entity<Category>()
       .HasMany(p => p.Products)
       .WithOne(p => p.Category)
       .HasForeignKey(p => p.CategoryId);

Here we’re specifying a relationship between tables. We say that a category has many products, and we set the properties that will map this relationship (Products, from Category class, and Category, from Product class). We also set the foreign key (CategoryId).

Take a look at this tutorial if you want to learn how to configure one-to-one and many-to-many relationships using EF Core, as well as how to use it as a whole.

There is also a configuration for seeding data, through the method HasData:

builder.Entity<Category>().HasData

(

  new Category { Id = 100, Name = “Fruits and Vegetables” },

  new Category { Id = 101, Name = “Dairy” }

);

Here we simply add two example categories by default. That’s necessary to test our API endpoint after we finish it.

Notice: we’re manually setting the Id properties here because the in-memory provider requires it to work. I’m setting the identifiers to big numbers to avoid collision between auto-generated identifiers and seed data.> Notice: we’re manually setting the Id properties here because the in-memory provider requires it to work. I’m setting the identifiers to big numbers to avoid collision between auto-generated identifiers and seed data.
Having implemented the database context class, we can implement the categories repository. Add a new folder called Repositories inside the Persistence folder, and then add a new class called BaseRepository.

using Supermarket.API.Persistence.Contexts;

namespace Supermarket.API.Persistence.Repositories
{
    public abstract class BaseRepository
    {
        protected readonly AppDbContext _context;

        public BaseRepository(AppDbContext context)
        {
            _context = context;
        }
    }
}

This class is just an abstract class that all our repositories will inherit. An abstract class is a class that don’t have direct instances. You have to create direct classes to create the instances.

The BaseRepository receives an instance of our AppDbContext through dependency injection and exposes a protected property (a property that can only be accessible by the children classes) called _context, that gives access to all methods we need to handle database operations.

Add a new class on the same folder called CategoryRepository. Now we’ll really implement the repository logic:

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Supermarket.API.Domain.Models;
using Supermarket.API.Domain.Repositories;
using Supermarket.API.Persistence.Contexts;

namespace Supermarket.API.Persistence.Repositories
{
    public class CategoryRepository : BaseRepository, ICategoryRepository
    {
        public CategoryRepository(AppDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<Category>> ListAsync()
        {
            return await _context.Categories.ToListAsync();
        }
    }
}

The repository inherits the BaseRepository and implements ICategoryRepository.

Notice how simple it is to implement the listing method. We use the Categories database set to access the categories table and then call the extension method ToListAsync, which is responsible for transforming the result of a query into a collection of categories.

The EF Core translates our method call to a SQL query, the most efficient way as possible. The query is only executed when you call a method that will transform your data into a collection, or when you use a method to take specific data.

We now have a clean implementation of the categories controller, the service and repository.

We have separated concerns, creating classes that only do what they are supposed to do.

The last step before testing the application is to bind our interfaces to the respective classes using the ASP.NET Core dependency injection mechanism.

Step 6 — Configuring Dependency Injection

It’s time for you to finally understand how this concept works.

In the root folder of the application, open the Startup class. This class is responsible for configuring all kinds of configurations when the application starts.

The ConfigureServices and Configure methods are called at runtime by the framework pipeline to configure how the application should work and which components it must use.

Have a look at the ConfigureServices method. Here we only have one line, that configures the application to use the MVC pipeline, which basically means the application is going to handle requests and responses using controller classes (there are more things happening here behind the scenes, but that’s what you need to know for now).

We can use the ConfigureServices method, accessing the services parameter, to configure our dependency bindings. Clean up the class code removing all comments and change the code as follows:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Supermarket.API.Domain.Repositories;
using Supermarket.API.Domain.Services;
using Supermarket.API.Persistence.Contexts;
using Supermarket.API.Persistence.Repositories;
using Supermarket.API.Services;

namespace Supermarket.API
{
    public class Startup
    {
        public IConfiguration Configuration { get; }

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddDbContext<AppDbContext>(options => {
                options.UseInMemoryDatabase("supermarket-api-in-memory");
            });

            services.AddScoped<ICategoryRepository, CategoryRepository>();
            services.AddScoped<ICategoryService, CategoryService>();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}

Look at this piece of code:

services.AddDbContext<AppDbContext>(options => {

  options.UseInMemoryDatabase(“supermarket-api-in-memory”);

});

Here we configure the database context. We tell ASP.NET Core to use our AppDbContext with an in-memory database implementation, that is identified by the string passed as an argument to our method. Usually, the in-memory provider is used when we write integration tests, but I’m using it here for simplicity. This way we don’t need to connect to a real database to test the application.

The configuration of these lines internally configures our database context for dependency injection using a scoped lifetime.

The scoped lifetime tells the ASP.NET Core pipeline that every time it needs to resolve a class that receives an instance of AppDbContext as a constructor argument, it should use the same instance of the class. If there is no instance in memory, the pipeline will create a new instance, and reuse it throughout all classes that need it, during a given request. This way, you don’t need to manually create the class instance when you need to use it.

There are other lifetime scopes that you can check reading the official documentation.

The dependency injection technique gives us many advantages, such as:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

After configuring the database context, we also bind our service and repository to the respective classes.

services.AddScoped<ICategoryRepository, CategoryRepository>();

services.AddScoped<ICategoryService, CategoryService>();

Here we also use a scoped lifetime because these classes internally have to use the database context class. It makes sense to specify the same scope in this case.

Now that we configure our dependency bindings, we have to make a small change at the Program class, in order for the database to correctly seed our initial data. This step is only needed when using the in-memory database provider (see this Github issue to understand why).

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Supermarket.API.Persistence.Contexts;

namespace Supermarket.API
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = BuildWebHost(args);

            using(var scope = host.Services.CreateScope())
            using(var context = scope.ServiceProvider.GetService<AppDbContext>())
            {
                context.Database.EnsureCreated();
            }

            host.Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
    }
}

It was necessary to change the Main method to guarantee that our database is going to be “created” when the application starts since we’re using an in-memory provider. Without this change, the categories that we want to seed won’t be created.

With all the basic features implemented, it’s time to test our API endpoint.

Step 7 — Testing the Categories API

Open the terminal or command prompt in the API root folder, and type the following command:

dotnet run

The command above starts the application. The console is going to show an output similar to this:

info: Microsoft.EntityFrameworkCore.Infrastructure[10403]

Entity Framework Core 2.2.0-rtm-35687 initialized ‘AppDbContext’ using provider ‘Microsoft.EntityFrameworkCore.InMemory’ with options: StoreName=supermarket-api-in-memory

info: Microsoft.EntityFrameworkCore.Update[30100]

Saved 2 entities to in-memory store.

info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]

User profile is available. Using ‘C:\Users\evgomes\AppData\Local\ASP.NET\DataProtection-Keys’ as key repository and Windows DPAPI to encrypt keys at rest.

Hosting environment: Development

Content root path: C:\Users\evgomes\Desktop\Tutorials\src\Supermarket.API

Now listening on: https://localhost:5001

Now listening on: http://localhost:5000

Application started. Press Ctrl+C to shut down.

You can see that EF Core was called to initialize the database. The last lines show in which ports the application is running.

Open a browser and navigate to http://localhost:5000/api/categories (or to the URL displayed on the console output). If you see a security error because of HTTPS, just add an exception for the application.

The browser is going to show the following JSON data as output:

[
  {
     “id”: 100,
     “name”: “Fruits and Vegetables”,
     “products”: []
  },
  {
     “id”: 101,
     “name”: “Dairy”,
     “products”: []
  }
]

Here we see the data we added to the database when we configured the database context. This output confirms that our code is working.

You created a GET API endpoint with really few lines of code, and you have a code structure that is really easy to change due to the architecture of the API.

Now, it’s time to show you how easy is to change this code when you have to adjust it due to business needs.

Step 8 — Creating a Category Resource

If you remember the specification of the API endpoint, you have noticed that our actual JSON response has one extra property: an array of products. Take a look at the example of the desired response:

{

  [

    { "id": 1, "name": "Fruits and Vegetables" },

    { "id": 2, "name": "Breads" },

    … // Other categories

  ]

}

The products array is present at our current JSON response because our Category model has a Products property, needed by EF Core to correct map the products of a given category.

We don’t want this property in our response, but we can’t change our model class to exclude this property. It would cause EF Core to throw errors when we try to manage categories data, and it would also break our domain model design because it does not make sense to have a product category that doesn’t have products.

To return JSON data containing only the identifiers and names of the supermarket categories, we have to create a resource class.

A resource class is a class that contains only basic information that will be exchanged between client applications and API endpoints, generally in form of JSON data, to represent some particular information.

All responses from API endpoints must return a resource.

It is a bad practice to return the real model representation as the response since it can contain information that the client application does not need or that it doesn’t have permission to have (for example, a user model could return information of the user password, which would be a big security issue).

We need a resource to represent only our categories, without the products.

Now that you know what a resource is, let’s implement it. First of all, stop the running application pressing Ctrl + C at the command line. In the root folder of the application, create a new folder called Resources. There, add a new class called CategoryResource.

namespace Supermarket.API.Resources
{
    public class CategoryResource
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

We have to map our collection of category models, that is provided by our category service, to a collection of category resources.

We’ll use a library called AutoMapper to handle mapping between objects. AutoMapper is a very popular library in the .NET world, and it is used in many commercial and open source projects.

Type the following lines into the command line to add AutoMapper to our application:

dotnet add package AutoMapper

dotnet add package AutoMapper.Extensions.Microsoft.DependencyInjection

To use AutoMapper, we have to do two things:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

First of all, open the Startup class. In the ConfigureServices method, after the last line, add the following code:

services.AddAutoMapper();

This line handles all necessary configurations of AutoMapper, such as registering it for dependency injection and scanning the application during startup to configure mapping profiles.

Now, in the root directory, add a new folder called Mapping, then add a class called ModelToResourceProfile. Change the code this way:

using AutoMapper;
using Supermarket.API.Domain.Models;
using Supermarket.API.Resources;

namespace Supermarket.API.Mapping
{
    public class ModelToResourceProfile : Profile
    {
        public ModelToResourceProfile()
        {
            CreateMap<Category, CategoryResource>();
        }
    }
}

The class inherits Profile, a class type that AutoMapper uses to check how our mappings will work. On the constructor, we create a map between the Category model class and the CategoryResource class. Since the classes’ properties have the same names and types, we don’t have to use any special configuration for them.

The final step consists of changing the categories controller to use AutoMapper to handle our objects mapping.

using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Supermarket.API.Domain.Models;
using Supermarket.API.Domain.Services;
using Supermarket.API.Resources;

namespace Supermarket.API.Controllers
{
    [Route("/api/[controller]")]
    public class CategoriesController : Controller
    {
        private readonly ICategoryService _categoryService;
        private readonly IMapper _mapper;

        public CategoriesController(ICategoryService categoryService, IMapper mapper)
        {
            _categoryService = categoryService;
            _mapper = mapper;
        }

        [HttpGet]
        public async Task<IEnumerable<CategoryResource>> GetAllAsync()
        {
            var categories = await _categoryService.ListAsync();
            var resources = _mapper.Map<IEnumerable<Category>, IEnumerable<CategoryResource>>(categories);
            
            return resources;
        }
    }
}

I changed the constructor to receive an instance of IMapper implementation. You can use these interface methods to use AutoMapper mapping methods.

I also changed the GetAllAsync method to map our enumeration of categories to an enumeration of resources using the Map method. This method receives an instance of the class or collection we want to map and, through generic type definitions, it defines to what type of class or collection must be mapped.

Notice that we easily changed the implementation without having to adapt the service class or repository, simply by injecting a new dependency (IMapper) to the constructor.

Dependency injection makes your application maintainable and easy to change since you don’t have to break all your code implementation to add or remove features.

You probably realized that not only the controller class but all classes that receive dependencies (including the dependencies themselves) were automatically resolved to receive the correct classes according to the binding configurations.

Dependency injection is amazing, isn’t it?

Now, start the API again using dotnet run command and head over to http://localhost:5000/api/categories to see the new JSON response.

We already have our GET endpoint. Now, let’s create a new endpoint to POST (create) categories.

Step 9 — Creating new Categories

When dealing with resources creation, we have to care about many things, such as:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

I won’t show how to deal with authorization in this tutorial, but you can see how to implement this feature reading my tutorial on JSON web token authentication.

Let’s write an HTTP POST endpoint that’s going to cover the other scenarios (except for logging, that can change according to different scopes and tools).

Before creating the new endpoint, we need a new resource. This resource will map data that client applications send to this endpoint (in this case, the category name) to a class of our application.

Since we’re creating a new category, we don’t have an ID yet, and it means we need a resource that represents a category containing only its name.

In the Resources folder, add a new class called SaveCategoryResource:

using System.ComponentModel.DataAnnotations;

namespace Supermarket.API.Resources
{
    public class SaveCategoryResource
    {
        [Required]
        [MaxLength(30)]
        public string Name { get; set; }
    }
}

Notice the Required and MaxLength attributes applied over the Name property. These attributes are called data annotations. The ASP.NET Core pipeline uses this metadata to validate requests and responses. As the names suggest, the category name is required and has a max length of 30 characters.

Now let’s define the shape of the new API endpoint. Add the following code to the categories controller:

[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] SaveCategoryResource resource)
{
}

We tell the framework that this is an HTTP POST endpoint using the HttpPost attribute.

Notice the response type of this method, Task<IActionResult>. Methods present in controller classes are called actions, and they have this signature because we can return more than one possible result after the application executes the action.

In this case, if the category name is invalid, or if something goes wrong, we have to return a 400 code (bad request) response, containing generally an error message that client apps can use to treat the problem, or we can have a 200 response (success) with data if everything goes ok.

There are many types of action types you can use as response, but generally, we can use this interface, and ASP.NET Core will use a default class for that.

The FromBody attribute tells ASP.NET Core to parse the request body data into our new resource class. It means that when a JSON containing the category name is sent to our application, the framework will automatically parse it to our new class.

Now, let’s implement our route logic. We have to follow some steps to successfully create a new category:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

It seems to be complicated, but it is really easy to implement this logic using the service architecture we structured for our API.

Let’s get started by validating the incoming request.

Step 10 — Validating the Request Body Using the Model State

ASP.NET Core controllers have a property called ModelState. This property is filled during request execution before reaching our action execution. It’s an instance of ModelStateDictionary, a class that contains information such as whether the request is valid and potential validation error messages.

Change the endpoint code as follows:

[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] SaveCategoryResource resource)
{
	if (!ModelState.IsValid)
		return BadRequest(ModelState.GetErrorMessages());
}

The code checks if the model state (in this case, the data sent in the request body) is invalid, checking our data annotations. If it isn’t, the API returns a bad request (with 400 status code) and the default error messages our annotations metadata provided.

The ModelState.GetErrorMessages()method isn’t implemented yet. It’s an extension method (a method that extends the functionality of an already existing class or interface) that I’m going to implement to convert the validation errors into simple strings to return to the client.

Add a new folder Extensions in the root of our API and then add a new class ModelStateExtensions.

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace Supermarket.API.Extensions
{
    public static class ModelStateExtensions
    {
        public static List<string> GetErrorMessages(this ModelStateDictionary dictionary)
        {
            return dictionary.SelectMany(m => m.Value.Errors)
                             .Select(m => m.ErrorMessage)
                             .ToList();
        }
    }
}

All extension methods should be static, as well as the classes where they are declared.It means they don’t handle specific instance data and that they’re loaded only once when the application starts.

The this keyword in front of the parameter declaration tells the C# compiler to treat it as an extension method. The result is that we can call it like a normal method of this class since we include the respective usingdirective where we want to use the extension.

The extension uses LINQ queries, a very useful feature of .NET that allows us to query and transform data using chainable expressions. The expressions here transform the validation error methods into a list of strings containing the error messages.

Import the namespace Supermarket.API.Extensions into the categories controller before going to the next step.

using Supermarket.API.Extensions;

Let’s continue implementing our endpoint logic by mapping our new resource to a category model class.

Step 11 — Mapping the new Resource

We have already defined a mapping profile to transform models into resources. Now we need a new profile that does the inverse.

Add a new class ResourceToModelProfile into the Mapping folder:

using AutoMapper;
using Supermarket.API.Domain.Models;
using Supermarket.API.Resources;

namespace Supermarket.API.Mapping
{
    public class ResourceToModelProfile : Profile
    {
        public ResourceToModelProfile()
        {
            CreateMap<SaveCategoryResource, Category>();
        }
    }
}

Nothing new here. Thanks to the magic of dependency injection, AutoMapper will automatically register this profile when the application starts, and we don’t have to change any other place to use it.

Now we can map our new resource to the respective model class:

HttpPost]
public async Task<IActionResult> PostAsync([FromBody] SaveCategoryResource resource)
{
	if (!ModelState.IsValid)
		return BadRequest(ModelState.GetErrorMessages());

	var category = _mapper.Map<SaveCategoryResource, Category>(resource);
}

Step 12 — Applying the Request-Response Pattern to Handle the Saving Logic

Now we have to implement the most interesting logic: to save a new category. We expect our service to do it.

The saving logic may fail due to problems when connecting to the database, or maybe because any internal business rule invalidates our data.

If something goes wrong, we can’t simply throw an error, because it could stop the API, and the client application wouldn’t know how to handle the problem. Also, we potentially would have some logging mechanism that would log the error.

The contract of the saving method, it means, the signature of the method and response type, needs to indicate us if the process was executed correctly. If the process goes ok, we’ll receive the category data. If not, we have to receive, at least, an error message telling why the process failed.

We can implement this feature by applying the request-response pattern. This enterprise design pattern encapsulates our request and response parameters into classes as a way to encapsulate information that our services will use to process some task and to return information to the class that is using the service.

This pattern gives us some advantages, such as:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

Let’s create a standard response type for our services methods that handle data changes. For every request of this type, we want to know if the request is executed with no problems. If it fails, we want to return an error message to the client.

In the Domain folder, inside Services, add a new directory called Communication. Add a new class there called BaseResponse.

namespace Supermarket.API.Domain.Services.Communication
{
    public abstract class BaseResponse
    {
        public bool Success { get; protected set; }
        public string Message { get; protected set; }

        public BaseResponse(bool success, string message)
        {
            Success = success;
            Message = message;
        }
    }
}

That’s an abstract class that our response types will inherit.

The abstraction defines a Success property, which will tell whether requests were completed successfully, and a Message property, that will have the error message if something fails.

Notice that these properties are required and only inherited classes can set this data because children classes have to pass this information through the constructor function.

Notice: we’re manually setting the Id properties here because the in-memory provider requires it to work. I’m setting the identifiers to big numbers to avoid collision between auto-generated identifiers and seed data.> Notice: we’re manually setting the Id properties here because the in-memory provider requires it to work. I’m setting the identifiers to big numbers to avoid collision between auto-generated identifiers and seed data.
Now, in the same folder, add a new class called SaveCategoryResponse.

using Supermarket.API.Domain.Models;

namespace Supermarket.API.Domain.Services.Communication
{
    public class SaveCategoryResponse : BaseResponse
    {
        public Category Category { get; private set; }

        private SaveCategoryResponse(bool success, string message, Category category) : base(success, message)
        {
            Category = category;
        }

        /// <summary>
        /// Creates a success response.
        /// </summary>
        /// <param name="category">Saved category.</param>
        /// <returns>Response.</returns>
        public SaveCategoryResponse(Category category) : this(true, string.Empty, category)
        { }

        /// <summary>
        /// Creates am error response.
        /// </summary>
        /// <param name="message">Error message.</param>
        /// <returns>Response.</returns>
        public SaveCategoryResponse(string message) : this(false, message, null)
        { }
    }
}

The response type also sets a Category property, which is going to contain our category data if the request successfully finishes.

Notice that I’ve defined three different constructors for this class:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

Because C# supports multiple constructors, we simplified the response creation without defining different method to handle this, just by using different constructors.

Now we can change our service interface to add the new save method contract.

Change the ICategoryService interface as follows:

using System.Collections.Generic;
using System.Threading.Tasks;
using Supermarket.API.Domain.Models;
using Supermarket.API.Domain.Services.Communication;

namespace Supermarket.API.Domain.Services
{
    public interface ICategoryService
    {
         Task<IEnumerable<Category>> ListAsync();
         Task<SaveCategoryResponse> SaveAsync(Category category);
    }
}

We’ll simply pass a category to this method and it will handle all logic necessary to save the model data, orchestrating repositories and other necessary services to do that.

Notice I’m not creating a specific request class here since we don’t need any other parameters to perform this task. There is a concept in computer programming called KISS — short for Keep it Simple, Stupid. Basically, it says that you should keep your application as simple as possible.

Remember this when designing your applications: apply only what you need to solve a problem. Don’t over-engineer your application.

Now we can finish our endpoint logic:

[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] SaveCategoryResource resource)
{
	if (!ModelState.IsValid)
		return BadRequest(ModelState.GetErrorMessages());

	var category = _mapper.Map<SaveCategoryResource, Category>(resource);
	var result = await _categoryService.SaveAsync(category);

	if (!result.Success)
		return BadRequest(result.Message);

	var categoryResource = _mapper.Map<Category, CategoryResource>(result.Category);
	return Ok(categoryResource);
}

After validating the request data and mapping the resource to our model, we pass it to our service to persist the data.

If something fails, the API returns a bad request. If not, the API maps the new category (now including data such as the new Id) to our previously created CategoryResource and sends it to the client.

Now let’s implement the real logic for the service.

Step 13 — The Database Login and the Unit of Work Pattern

Since we’re going to persist data into the database, we need a new method in our repository.

Add a new AddAsync method to the ICategoryRepository interface:

public interface ICategoryRepository
{
	 Task<IEnumerable<Category>> ListAsync();
	 Task AddAsync(Category category);
}

Now, let’s implement this method at our real repository class:

public class CategoryRepository : BaseRepository, ICategoryRepository
{
	public CategoryRepository(AppDbContext context) : base(context)
	{ }

	public async Task<IEnumerable<Category>> ListAsync()
	{
		return await _context.Categories.ToListAsync();
	}

	public async Task AddAsync(Category category)
	{
		await _context.Categories.AddAsync(category);
	}
}

Here we’re simply adding a new category to our set.

When we add a class to a DBSet<>, EF Core starts tracking all changes that happen to our model and uses this data at the current state to generate queries that will insert, update or delete models.

The current implementation simply adds the model to our set, but our data still won’t be saved.

There is a method called SaveChanges present at the context class that we have to call to really execute the queries into the database. I didn’t call it here because a repository shouldn’t persist data, it’s just an in-memory collection of objects.

This subject is very controversial even between experienced .NET developers, but let me explain to you why you shouldn’t call SaveChanges in repository classes.

We can think of a repository conceptually as any other collection present at the .NET framework. When dealing with a collection in .NET (and many other programming languages, such as Javascript and Java), you generally can:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

Think of a list from the real world. Imagine you’re writing a shopping list to buy things at a supermarket (what a coincidence, no?).

In the list, you write all the fruits you need to buy. You can add fruits to this list, remove a fruit if you give up buying it, or you can replace a fruit’s name. But you can’t save fruits into the list. It doesn’t make sense to say such a thing in plain English.

Notice: we’re manually setting the Id properties here because the in-memory provider requires it to work. I’m setting the identifiers to big numbers to avoid collision between auto-generated identifiers and seed data.> Notice: we’re manually setting the Id properties here because the in-memory provider requires it to work. I’m setting the identifiers to big numbers to avoid collision between auto-generated identifiers and seed data.
If you want to “save” the fruits lists (in this case, to buy all fruits), you pay it and the supermarket processes the stock data to check if they have to buy more fruits from a provider or not.

The same logic can be applied when programming. Repositories shouldn’t save, update or delete data. Instead, they should delegate it to a different class to handle this logic.

There is another problem when saving data directly into a repository: you can’t use transactions.

Imagine that our application has a logging mechanism that stores some username and the action performed every time a change is made to the API data.

Now imagine that, for some reason, you have a call to a service that updates the username (it’s not a common scenario, but let’s consider it).

You agree that to change the username in a fictional users table, you first have to update all logs to correctly tell who performed that operation, right?

Now imagine we have implemented the update method for users and logs in different repositories, and them both call SaveChanges. What happens if one of these methods fails in the middle of the updating process? You’ll end up with data inconsistency.

We should save our changes into the database only after everything finishes. To do this, we have to use a transaction, that is basically a feature most databases implement to save data only after a complex operation finishes.

“ - Ok, so if we can’t save things here, where should we do it?”

A common pattern to handle this issue is the Unit of Work Pattern. This pattern consists of a class that receives our AppDbContext instance as a dependency and exposes methods to start, complete or abort transactions.

We’ll use a simple implementation of a unit of work to approach our problem here.

Add a new interface inside the Repositories folder of the Domain layer called IUnitOfWork:

using System.Threading.Tasks;

namespace Supermarket.API.Domain.Repositories
{
    public interface IUnitOfWork
    {
         Task CompleteAsync();
    }
}

As you can see, it only exposes a method that will asynchronously complete data management operations.

Let’s add the real implementation now.

Add a new class called UnitOfWork at the RepositoriesRepositories folder of the Persistence layer:

using System.Threading.Tasks;
using Supermarket.API.Domain.Repositories;
using Supermarket.API.Persistence.Contexts;

namespace Supermarket.API.Persistence.Repositories
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly AppDbContext _context;

        public UnitOfWork(AppDbContext context)
        {
            _context = context;     
        }

        public async Task CompleteAsync()
        {
            await _context.SaveChangesAsync();
        }
    }
}

That’s a simple, clean implementation that will only save all changes into the database after you finish modifying it using your repositories.

If you research implementations of the Unit of Work pattern, you’ll find more complex ones implementing rollback operations.

Since EF Core already implement the repository pattern and unit of work behind the scenes, we don’t have to care about a rollback method.

“ - What? So why do we have to create all these interfaces and classes?”

Separating the persistence logic from business rules gives many advantages in terms of code reusability and maintenance. If we use EF Core directly, we’ll end up having more complex classes that won’t be so easy to change.

Imagine that in the future you decide to change the ORM framework to a different one, such as Dapper, for example, or if you have to implement plain SQL queries because of performance. If you couple your queries logic to your services, it will be difficult to change the logic, because you’ll have to do it in many classes.

Using the repository pattern, you can simply implement a new repository class and bind it using dependency injection.

So, basically, if you use EF Core directly into your services and you have to change something, that’s what you’ll get:

As I said, EF Core implements the Unit of Work and Repository patterns behind the scenes. We can consider our DbSet<>properties as repositories. Also, SaveChanges only persists data in case of success for all database operations.

Now that you know what is a unit of work and why to use it with repositories, let’s implement the real service’s logic.

public class CategoryService : ICategoryService
{
	private readonly ICategoryRepository _categoryRepository;
	private readonly IUnitOfWork _unitOfWork;

	public CategoryService(ICategoryRepository categoryRepository, IUnitOfWork unitOfWork)
	{
		_categoryRepository = categoryRepository;
		_unitOfWork = unitOfWork;
	}

	public async Task<IEnumerable<Category>> ListAsync()
	{
		return await _categoryRepository.ListAsync();
	}

	public async Task<SaveCategoryResponse> SaveAsync(Category category)
	{
		try
		{
			await _categoryRepository.AddAsync(category);
			await _unitOfWork.CompleteAsync();
			
			return new SaveCategoryResponse(category);
		}
		catch (Exception ex)
		{
			// Do some logging stuff
			return new SaveCategoryResponse($"An error occurred when saving the category: {ex.Message}");
		}
	}
}

Thanks to our decoupled architecture, we can simply pass an instance of UnitOfWork as a dependency for this class.

Our business logic is pretty simple.

First, we try to add the new category to the database and then the API try to save it, wrapping everything inside a try-catch block.

If something fails, the API calls some fictional logging service and return a response indicating failure.

If the process finishes with no problems, the application returns a success response, sending our category data. Simple, right?

Notice: we’re manually setting the Id properties here because the in-memory provider requires it to work. I’m setting the identifiers to big numbers to avoid collision between auto-generated identifiers and seed data.> Notice: we’re manually setting the Id properties here because the in-memory provider requires it to work. I’m setting the identifiers to big numbers to avoid collision between auto-generated identifiers and seed data.
The last step before testing our API is to bind the unit of work interface to its respective class.

Add this new line to the ConfigureServices method of the Startup class:

services.AddScoped<IUnitOfWork, UnitOfWork>();

Now let’s test it!

Step 14 — Testing our POST Endpoint using Postman

Start our application again using dotnet run.

We can’t use the browser to test a POST endpoint. Let’s use Postman to test our endpoints. It’s a very useful tool to test RESTful APIs.

Open Postman and close the intro messages. You’ll see a screen like this one:

Change the GET selected by default into the select box to POST.

Type the API address into the Enter request URL field.

We have to provide the request body data to send to our API. Click on the Body menu item, then change the option displayed below it to raw.

Postman will show a Text option in the right. Change it to JSON (application/json) and paste the following JSON data below:

{

  "name": ""

}

As you see, we’re going to send an empty name string to our new endpoint.

Click the Send button. You’ll receive an output like this:

Do you remember the validation logic we created for the endpoint? This output is the proof it works!

Notice also the 400 status code displayed at the right. The BadRequest result automatically adds this status code to the response.

Now let’s change the JSON data to a valid one to see the new response:

The API correctly created our new resource.

Until now, our API can list and create categories. You learned a lot of things about the C# language, the ASP.NET Core framework and also common design approaches to structure your APIs.

Let’s continue our categories API creating the endpoint to update categories.

From now on, since I explained you most concepts, I’ll speed up the explanations and focus on new subjects to not waste your time. Let’s go!

Step 15 — Updating Categories

To update categories, we need an HTTP PUT endpoint.

The logic we have to code is very similar to the POST one:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

Let’s add the new PutAsync method into the controller class:

[HttpPut("{id}")]
public async Task<IActionResult> PutAsync(int id, [FromBody] SaveCategoryResource resource)
{
	if (!ModelState.IsValid)
		return BadRequest(ModelState.GetErrorMessages());

	var category = _mapper.Map<SaveCategoryResource, Category>(resource);
	var result = await _categoryService.UpdateAsync(id, category);

	if (!result.Success)
		return BadRequest(result.Message);

	var categoryResource = _mapper.Map<Category, CategoryResource>(result.Category);
	return Ok(categoryResource);
}

If you compare it with the POST logic, you’ll notice we have only one difference here: the HttPut attribute specifies a parameter that the given route should receive.

We’ll call this endpoint specifying the category Id as the last URL fragment, like /api/categories/1. The ASP.NET Core pipeline parse this fragment to the parameter of the same name.

Now we have to define the UpdateAsync method signature into the ICategoryService interface:

public interface ICategoryService
{
	Task<IEnumerable<Category>> ListAsync();
	Task<SaveCategoryResponse> SaveAsync(Category category);
	Task<SaveCategoryResponse> UpdateAsync(int id, Category category);
}

Now let’s move to the real logic.

Step 16 — The Update Logic

To update our category, first, we need to return the current data from the database, if it exists. We also need to update it into our DBSet<>.

Let’s add two new method contracts to our ICategoryService interface:

public interface ICategoryRepository
{
	Task<IEnumerable<Category>> ListAsync();
	Task AddAsync(Category category);
	Task<Category> FindByIdAsync(int id);
	void Update(Category category);
}

We’ve defined the FindByIdAsync method, that will asynchronously return a category from the database, and the Update method. Pay attention that the Update method isn’t asynchronous since the EF Core API does not require an asynchronous method to update models.

Now let’s implement the real logic into the CategoryRepository class:

public async Task<Category> FindByIdAsync(int id)
{
	return await _context.Categories.FindAsync(id);
}

public void Update(Category category)
{
	_context.Categories.Update(category);
}

Finally we can code the service logic:

public async Task<SaveCategoryResponse> UpdateAsync(int id, Category category)
{
	var existingCategory = await _categoryRepository.FindByIdAsync(id);

	if (existingCategory == null)
		return new SaveCategoryResponse("Category not found.");

	existingCategory.Name = category.Name;

	try
	{
		_categoryRepository.Update(existingCategory);
		await _unitOfWork.CompleteAsync();

		return new SaveCategoryResponse(existingCategory);
	}
	catch (Exception ex)
	{
		// Do some logging stuff
		return new SaveCategoryResponse($"An error occurred when updating the category: {ex.Message}");
	}
}

The API tries to get the category from the database. If the result is null, we return a response telling that the category does not exist. If the category exists, we need to set its new name.

The API, then, tries to save changes, like when we create a new category. If the process completes, the service returns a success response. If not, the logging logic executes, and the endpoint receives a response containing an error message.

Now let’s test it. First, let’s add a new category to have a valid Id to use. We could use the identifiers of the categories we seed to our database, but I want to do it this way to show you that our API is going to update the correct resource.

Run the application again and, using Postman, POST a new category to the database:

Having a valid Id in hands, change the POST option to PUT into the select box and add the ID value at the end of the URL. Change the name property to a different name and send the request to check the result:

You can send a GET request to the API endpoint to assure you correctly edited the category name:

The last operation we have to implement for categories is the exclusion of categories. Let’s do it creating an HTTP Delete endpoint.

Step 17 — Deleting Categories

The logic for deleting categories is really easy to implement since most methods we need were built previously.

These are the necessary steps for our route to work:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

Let’s get started by adding the new endpoint logic:

[HttpDelete("{id}")]
public async Task<IActionResult> DeleteAsync(int id)
{
	var result = await _categoryService.DeleteAsync(id);

	if (!result.Success)
		return BadRequest(result.Message);

	var categoryResource = _mapper.Map<Category, CategoryResource>(result.Category);
	return Ok(categoryResource);
}

The HttpDelete attribute also defines an id template.

Before adding the DeleteAsync signature to our ICategoryService interface, we need to do a small refactoring.

The new service method must return a response containing the category data, the same way we did for the PostAsync and UpdateAsync methods. We could reuse the SaveCategoryResponse for this purpose, but we’re not saving data in this case.

To avoid creating a new class with the same shape to deliver this requirement, we can simply rename our SaveCategoryResponse to CategoryResponse.

If you’re using Visual Studio Code, you can open the SaveCategoryResponse class, put the mouse cursor above the class name and use the option Change All Occurrencesto rename the class:

Be sure to rename the filename too.

Let’s add the DeleteAsync method signature to the ICategoryService interface:

public interface ICategoryService
{
	Task<IEnumerable<Category>> ListAsync();
	Task<CategoryResponse> SaveAsync(Category category);
	Task<CategoryResponse> UpdateAsync(int id, Category category);
	Task<CategoryResponse> DeleteAsync(int id);
}

Before implementing the deletion logic, we need a new method in our repository.

Add the Remove method signature to the ICategoryRepository interface:

void Remove(Category category);

And now add the real implementation on the repository class:

public void Remove(Category category)
{
	_context.Categories.Remove(category);
}

EF Core requires the instance of our model to be passed to the Remove method to correctly understand which model we’re deleting, instead of simply passing an Id.

Finally, let’s implement the logic on CategoryService class:

public async Task<CategoryResponse> DeleteAsync(int id)
{
	var existingCategory = await _categoryRepository.FindByIdAsync(id);

	if (existingCategory == null)
		return new CategoryResponse("Category not found.");

	try
	{
		_categoryRepository.Remove(existingCategory);
		await _unitOfWork.CompleteAsync();

		return new CategoryResponse(existingCategory);
	}
	catch (Exception ex)
	{
		// Do some logging stuff
		return new CategoryResponse($"An error occurred when deleting the category: {ex.Message}");
	}
}

There’s nothing new here. The service tries to find the category by ID and then it calls our repository to delete the category. Finally, the unit of work completes the transaction executing the real operation into the database.

“ - Hey, but how about the products of each category? Don’t you need to create a repository and delete the products first, to avoid errors?”

The answer is no. Thanks to EF Core tracking mechanism, when we load a model from the database, the framework knows which relationships the model has. If we delete it, EF Core knows it should delete all related models first, recursively.

We can disable this feature when mapping our classes to database tables, but it’s out of scope for this tutorial. Take a look here if you want to learn about this feature.

Now it’s time to test our new endpoint. Run the application again and send a DELETE request using Postman as follows:

We can check that our API is correctly working by sending a GET request:

We’ve finished the categories API. Now it’s time to move to the products API.

Step 18 — The Products API

So far you have learned how to implement all basic HTTP verbs to handle CRUD operations with ASP.NET Core. Let’s go to the next level implementing our products API.

I won’t detail all HTTP verbs again because it would be exhaustive. For the final part of this tutorial, I’ll cover only the GET request, to show you how to include related entities when querying data from the database and how to use the Description attributes we defined for the EUnitOfMeasurement enumeration values.

Add a new controller into the Controllers folder called ProductsController.

Before coding anything here, we have to create the product resource.

Let me refresh your memory showing again how our resource should look like:

{
 [
  {
   "id": 1,
   "name": "Sugar",
   "quantityInPackage": 1,
   "unitOfMeasurement": "KG"
   "category": {
   "id": 3,
   "name": "Sugar"
   }
  },
  … // Other products
 ]
}

We want a JSON array containing all products from the database.

The JSON data differs from the product model by two things:

  • Create a RESTful service that allows client applications to manage the supermarket’s product catalog. It needs to expose endpoints to create, read, edit and delete products categories, such as dairy products and cosmetics, and also to manage products of these categories.
  • For categories, we need to store their names. For products, we need to store their names, unit of measurement (for example, KG for products measured by weight), quantity in the package (for example, 10 if the product is a pack of biscuits) and their respective categories.

To represent the unit of measurement, we can use a simple string property instead of an enum type (by the way, we don’t have a default enum type for JSON data, so we have to transform it into a different type).

Now that we now how to shape the new resource, let’s create it. Add a new class ProductResource into the Resources folder:

namespace Supermarket.API.Resources
{
    public class ProductResource
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int QuantityInPackage { get; set; }
        public string UnitOfMeasurement { get; set; }
        public CategoryResource Category {get;set;}
    }
}

Now we have to configure the mapping between the model class and our new resource class.

The mapping configuration will be almost the same as the ones used for other mappings, but here we have to handle the transformation of our EUnitOfMeasurement enum to a string.

Do you remember the StringValue attribute applied over the enumeration types? Now I’ll show you how to extract this information using a powerful feature of the .NET framework: the Reflection API.

The Reflection API is a powerful set of resources that allows us to extract and manipulate metadata. A lot of frameworks and libraries (including ASP.NET Core itself) make use of these resources to handle many things behind the scenes.

Now let’s see how it works in practice. Add a new class into the Extensions folder called EnumExtensions.

using System.ComponentModel;
using System.Reflection;

namespace Supermarket.API.Extensions
{
    public static class EnumExtensions
    {
        public static string ToDescriptionString<TEnum>(this TEnum @enum)
        {
            FieldInfo info = @enum.GetType().GetField(@enum.ToString());
            var attributes = (DescriptionAttribute[])info.GetCustomAttributes(typeof(DescriptionAttribute), false);

            return attributes?[0].Description ?? @enum.ToString();
        }
    }
}

It may seem scaring the first time you look at the code, but it’s not so complex. Let’s break down the code definition to understand how it works.

First, we defined a generic method (a method that can receive more than one type of argument, in this case, represented by the TEnum declaration) that receives a given enum as an argument.

Since enum is a reserved keyword in C#, we added an @ in front of the parameter’s name to make it a valid name.

The first execution step of this method is to get the type information (the class, interface, enum or struct definition) of the parameter using the GetType method.

Then, the method gets the specific enumeration value (for instance, Kilogram) using GetField(@enum.ToString()).

The next line finds all Description attributes applied over the enumeration value and stores their data into an array (we can specify multiple attributes for a same property in some cases).

The last line uses a shorter syntax to check if we have at least one description attribute for the enumeration type. If we have, we return the Description value provided by this attribute. If not, we return the enumeration as a string, using the default casting.

The ?. operator (a null-conditional operator) checks if the value is null before accessing its property.

The ?? operator (a null-coalescing operator) tells the application to return the value at the left if it’s not empty, or the value at right otherwise.

Now that we have an extension method to extract descriptions, let’s configure our mapping between model and resource. Thanks to AutoMapper, we can do it with only one extra line.

Open the ModelToResourceProfile class and change the code this way:

using AutoMapper;
using Supermarket.API.Domain.Models;
using Supermarket.API.Extensions;
using Supermarket.API.Resources;

namespace Supermarket.API.Mapping
{
    public class ModelToResourceProfile : Profile
    {
        public ModelToResourceProfile()
        {
            CreateMap<Category, CategoryResource>();

            CreateMap<Product, ProductResource>()
                .ForMember(src => src.UnitOfMeasurement,
                           opt => opt.MapFrom(src => src.UnitOfMeasurement.ToDescriptionString()));
        }
    }
}

This syntax tells AutoMapper to use the new extension method to convert our EUnitOfMeasurement value into a string containing its description. Simple, right? You can read the official documentation to understand the full syntax.

Notice we haven’t defined any mapping configuration for the category property. Because we previously configured the mapping for categories and because the product model has a category property of the same type and name, AutoMapper implicitly knows that it should map it using the respective configuration.

Now let’s add the endpoint code. Change the ProductsController code:

using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Supermarket.API.Domain.Models;
using Supermarket.API.Domain.Services;
using Supermarket.API.Resources;

namespace Supermarket.API.Controllers
{
    [Route("/api/[controller]")]
    public class ProductsController : Controller
    {
        private readonly IProductService _productService;
        private readonly IMapper _mapper;

        public ProductsController(IProductService productService, IMapper mapper)
        {
            _productService = productService;
            _mapper = mapper;
        }

        [HttpGet]
        public async Task<IEnumerable<ProductResource>> ListAsync()
        {
            var products = await _productService.ListAsync();
            var resources = _mapper.Map<IEnumerable<Product>, IEnumerable<ProductResource>>(products);
            return resources;
        }
    }
}

Basically, the same structure defined for the categories controller.

Let’s go to the service part. Add a new IProductService interface into the Services folder present at the Domain layer:

using System.Collections.Generic;
using System.Threading.Tasks;
using Supermarket.API.Domain.Models;

namespace Supermarket.API.Domain.Services
{
    public interface IProductService
    {
         Task<IEnumerable<Product>> ListAsync();
    }
}

You should have realized we need a repository before really implementing the new service.

Add a new interface called IProductRepository into the respective folder:

using System.Collections.Generic;
using System.Threading.Tasks;
using Supermarket.API.Domain.Models;

namespace Supermarket.API.Domain.Repositories
{
    public interface IProductRepository
    {
         Task<IEnumerable<Product>> ListAsync();
    }
}

Now let’s implement the repository. We have to implement it almost the same way we did for the categories repository, except that we need to return the respective category data of each product when querying data.

EF Core, by default, does not include related entities to your models when you querying data because it could be very slow (imagine a model with ten related entities, all all related entities having its own relationships).

To include the categories data, we need only one extra line:

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Supermarket.API.Domain.Models;
using Supermarket.API.Domain.Repositories;
using Supermarket.API.Persistence.Contexts;

namespace Supermarket.API.Persistence.Repositories
{
    public class ProductRepository : BaseRepository, IProductRepository
    {
        public ProductRepository(AppDbContext context) : base(context)
        {
        }

        public async Task<IEnumerable<Product>> ListAsync()
        {
            return await _context.Products.Include(p => p.Category)
                                          .ToListAsync();
        }
    }
}

Notice the call to Include(p => p.Category). We can chain this syntax to include as many entities as necessary when querying data. EF Core is going to translate it to a join when performing the select.

Now we can implement the ProductService class the same way we did for categories:

using System.Collections.Generic;
using System.Threading.Tasks;
using Supermarket.API.Domain.Models;
using Supermarket.API.Domain.Repositories;
using Supermarket.API.Domain.Services;

namespace Supermarket.API.Services
{
    public class ProductService : IProductService
    {
        private readonly IProductRepository _productRepository;
    
        public ProductService(IProductRepository productRepository)
        {
            _productRepository = productRepository;
        }

        public async Task<IEnumerable<Product>> ListAsync()
        {
            return await _productRepository.ListAsync();
        }
    }
}

Let’s bind the new dependencies changing the Startup class:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    services.AddDbContext<AppDbContext>(options =>
    {
        options.UseInMemoryDatabase("supermarket-api-in-memory");
    });

    services.AddScoped<ICategoryRepository, CategoryRepository>();
    services.AddScoped<IProductRepository, ProductRepository>();
    services.AddScoped<IUnitOfWork, UnitOfWork>();

    services.AddScoped<ICategoryService, CategoryService>();
    services.AddScoped<IProductService, ProductService>();

    services.AddAutoMapper();
}

Finally, before testing the API, let’s change the AppDbContext class to include some products when initializing the application so we can see the results:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    
    builder.Entity<Category>().ToTable("Categories");
    builder.Entity<Category>().HasKey(p => p.Id);
    builder.Entity<Category>().Property(p => p.Id).IsRequired().ValueGeneratedOnAdd().HasValueGenerator<InMemoryIntegerValueGenerator<int>>();
    builder.Entity<Category>().Property(p => p.Name).IsRequired().HasMaxLength(30);
    builder.Entity<Category>().HasMany(p => p.Products).WithOne(p => p.Category).HasForeignKey(p => p.CategoryId);

    builder.Entity<Category>().HasData
    (
        new Category { Id = 100, Name = "Fruits and Vegetables" }, // Id set manually due to in-memory provider
        new Category { Id = 101, Name = "Dairy" }
    );

    builder.Entity<Product>().ToTable("Products");
    builder.Entity<Product>().HasKey(p => p.Id);
    builder.Entity<Product>().Property(p => p.Id).IsRequired().ValueGeneratedOnAdd();
    builder.Entity<Product>().Property(p => p.Name).IsRequired().HasMaxLength(50);
    builder.Entity<Product>().Property(p => p.QuantityInPackage).IsRequired();
    builder.Entity<Product>().Property(p => p.UnitOfMeasurement).IsRequired();

    builder.Entity<Product>().HasData
    (
        new Product
        {
            Id = 100,
            Name = "Apple",
            QuantityInPackage = 1,
            UnitOfMeasurement = EUnitOfMeasurement.Unity,
            CategoryId = 100
        },
        new Product
        {
            Id = 101,
            Name = "Milk",
            QuantityInPackage = 2,
            UnitOfMeasurement = EUnitOfMeasurement.Liter,
            CategoryId = 101,
        }
    );
}

I added two fictional products associating them to the categories we seed when initializing the application.

Time to test! Run the API again and send a GET request to /api/products using Postman:

And that’s it! Congratulations!

Now you have a base on how to build a RESTful API using ASP.NET Core using a decoupled architecture. You learned many things of the .NET Core framework, how to work with C#, the basics of EF Core and AutoMapper and many useful patterns to use when designing your applications.

You can check the full implementation of the API, containing the others HTTP verbs for products, checking the [Github] (https://github.com/evgomes/supermarket-api “”)repository:

Conclusion

ASP.NET Core is a great framework to use when creating web applications. It comes with many useful APIs you can use to build clean, maintainable applications. Consider it as an option when creating professional applications.

This article hasn’t covered all aspects of a professional API, but you learned all the basics. You also learned many useful patterns to solve patterns we face daily.

I hope you enjoyed this article and I hope it was useful for you. I appreciate your feedback to understand how I can improve this.

References to Keep Learning

.NET Core Tutorials — Microsoft Docs

ASP.NET Core Documentation — Microsoft Docs

Learn More

The Complete ASP.NET MVC 5 Course

Build a Real-world App with ASP.NET Core and Angular 2 (4+)

ASP NET Core (ASP.NET 5),MVC 6,C#,Angular2 & EF Crash Course

Rest Api’s in Asp.Net and C#

Hands on ASP .Net Core 2

How To Create Chat App in PHP Using Ajax and JQuery

How To Create Chat App in PHP Using Ajax and JQuery

In this tutorial, you'll learn how to create chat system in PHP using Ajax and JQuery

Chat App is a favorite application which every programmer want to be make their own chat application in their programming career. This Chat application mostly used to communicate with friends and in business world company has communicate with their customer to provide assistant or help to customer regarding their services or product which they has offered. So, it is very important application which required in every website or web application. So, this type of system we have start to make in step by step process by using PHP script with Ajax Jquery Mysql Bootstrap and JQuery UI library.

Do you know real time chat application, real time chat application means we can communicate multiple person at the same time, so there are many business houses use a chat application for communicate with their customer in real time and provide services. For the importance of this chat system we have decided to publish tutorial on chat application in php and mysql using Ajax JQuery.

So, in this post we are going to make simple chat application by using Ajax Jquery and PHP programming and Mysql database. Ajax with Jquery script is used to send and received request for data from client machine to server and server to client machine using PHP. It is mainly used for create real time application for send and received data without refresh of web page. In the real web world, we have generally use HTTP request GET and POST method for communication done between client and server side. In this PHP Chat application we have use Ajax Jquery to communicate with the server. Below you can find complete step by step process for create Chat Application in PHP using Ajax.

How To Create Chat App in PHP Using Ajax and JQuery

Database Structure for PHP Ajax Chat Application

Here this is Mysql database structure for PHP Mysql chat system. Following tables we will use to make chat app.


--
-- Database: `chat`
--

-- --------------------------------------------------------

--
-- Table structure for table `chat_message`
--

CREATE TABLE `chat_message` (
  `chat_message_id` int(11) NOT NULL,
  `to_user_id` int(11) NOT NULL,
  `from_user_id` int(11) NOT NULL,
  `chat_message` text NOT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `status` int(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Table structure for table `login`
--

CREATE TABLE `login` (
  `user_id` int(11) NOT NULL,
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `login`
--

INSERT INTO `login` (`user_id`, `username`, `password`) VALUES
(1, 'johnsmith', '$2y$10$4REfvTZpxLgkAR/lKG9QiOkSdahOYIR3MeoGJAyiWmRkEFfjH3396'),
(2, 'peterParker', '$2y$10$4REfvTZpxLgkAR/lKG9QiOkSdahOYIR3MeoGJAyiWmRkEFfjH3396'),
(3, 'davidMoore', '$2y$10$4REfvTZpxLgkAR/lKG9QiOkSdahOYIR3MeoGJAyiWmRkEFfjH3396');

-- --------------------------------------------------------

--
-- Table structure for table `login_details`
--

CREATE TABLE `login_details` (
  `login_details_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `last_activity` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `is_type` enum('no','yes') NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Indexes for dumped tables
--

--
-- Indexes for table `chat_message`
--
ALTER TABLE `chat_message`
  ADD PRIMARY KEY (`chat_message_id`);

--
-- Indexes for table `login`
--
ALTER TABLE `login`
  ADD PRIMARY KEY (`user_id`);

--
-- Indexes for table `login_details`
--
ALTER TABLE `login_details`
  ADD PRIMARY KEY (`login_details_id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `chat_message`
--
ALTER TABLE `chat_message`
  MODIFY `chat_message_id` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT for table `login`
--
ALTER TABLE `login`
  MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;

--
-- AUTO_INCREMENT for table `login_details`
--
ALTER TABLE `login_details`
  MODIFY `login_details_id` int(11) NOT NULL AUTO_INCREMENT;

Once you have make chat database and above table in your mysql database then you have to make database connection. For making database connection using PHP PDO we have to write following code.


<?php

//database_connection.php

$connect = new PDO("mysql:host=localhost;dbname=chat", "root", "");

?>

Make Login and Logout page for chat application using PHP and Jquery

Once you have make database connection then after we want to make login and logout page for our PHP Mysql Chat system. We all know Login into a system is one type of process in which an user can gain access into our web application by identifying their authenticating their identity to system. So here for using our Live Chat Application we have to make Login and logout process, so we can authenticating user identity and get access them to gain our chat application. And by clicking on logout link they can leave our Chat app. Below you can find login source code for this PHP Ajax Chat script.

View Demo

<!--
//login.php
!-->

<?php

include('database_connection.php');

session_start();

$message = '';

if(isset($_SESSION['user_id']))
{
 header('location:index.php');
}

if(isset($_POST["login"]))
{
 $query = "
   SELECT * FROM login 
    WHERE username = :username
 ";
 $statement = $connect->prepare($query);
 $statement->execute(
    array(
      ':username' => $_POST["username"]
     )
  );
  $count = $statement->rowCount();
  if($count > 0)
 {
  $result = $statement->fetchAll();
    foreach($result as $row)
    {
      if(password_verify($_POST["password"], $row["password"]))
      {
        $_SESSION['user_id'] = $row['user_id'];
        $_SESSION['username'] = $row['username'];
        $sub_query = "
        INSERT INTO login_details 
        (user_id) 
        VALUES ('".$row['user_id']."')
        ";
        $statement = $connect->prepare($sub_query);
        $statement->execute();
        $_SESSION['login_details_id'] = $connect->lastInsertId();
        header("location:index.php");
      }
      else
      {
       $message = "Wrong Password";
      }
    }
 }
 else
 {
  $message = "Wrong Username";
 }
}

?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
  
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
      Chat Application Login

    
     
      


      
       Enter Username
       
      
      
       Enter Password
       
      
      
       
      
     
    
   
  
      


How To Create Chat App in PHP Using Ajax and JQuery

This is simple login page code for our PHP Chat application. Here we have authenticate user details like username and password. If this both details is proper then he can get access into this online chat system. Otherwise it will get wrong information error on web page. Suppose user has enter proper details then he can get access into our live chat app. Here we have store hash password in database, so for validate hash password we have use password_verify() function. By using this function this system can authenticate user password. After authenticate process particular user details like user id and user name has been store into $_SESSION variable and this variable value we can from accross system. Particular user login details like his user id and timestamp details has been inserted into login_details table. After inserting their login details into database then last inserted id of login_details table has been get by using lastInsertId() method and store into $_SESSION['login_details_id'] variable. This data will help use to know particular user online status like he is onlin and offline. So, this whole discussion of login table.

After login in Chat Application user will be redirect to index page. Below you can find index page source code. This page cannot access directly without login into system because for access this page we want to login into system. So, authenticated used can only access this page. For this here we have validate $_SESSION['user_id'] variable value. Here you can find logout page link also.

<!--
//index.php
!-->

<?php

include('database_connection.php');

session_start();

if(!isset($_SESSION['user_id']))
{
 header('location:login.php');
}
?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
  
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
   
    #### Online User

    
Hi -  - [Logout](logout.php "Logout")

    
   
  
      
  

Above code is index.php code and this page can be access only after login into Chat system. Here we can see logout link also. Once we have click on this link we will be logout from this system and page has been redirect to login.php page. Below you can find logout.php page code.


<?php

//logout.php

session_start();

session_destroy();

header('location:login.php');

?>

How To Create Chat App in PHP Using Ajax and JQuery

Display User Data in PHP Ajax Chat system

After complete discuss of login and logout source code. Now we have move to next stage of Chat Application development and this stag is display all user data on web page when user login into Chat application and after validate user data then he will redirect to index.php page. On this page we want to display all user data which are available in login table. So login user can decide to which person he want to login. In this step we have simple fetch user data from login table and display on index page. Below you can source code for display user details on web page.


<!--
//index.php
!-->

<?php

include('database_connection.php');

session_start();

if(!isset($_SESSION['user_id']))
{
 header("location:login.php");
}

?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
  
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
   
    #### Online User

    
Hi -  - [Logout](logout.php "Logout")

    

   
  
      
  








<?php

//fetch_user.php

include('database_connection.php');

session_start();

$query = "
SELECT * FROM login 
WHERE user_id != '".$_SESSION['user_id']."' 
";

$statement = $connect->prepare($query);

$statement->execute();

$result = $statement->fetchAll();

$output = '

 
  Username
  Status
  Action
 
';

foreach($result as $row)
{
 $output .= '
 
  '.$row['username'].'
  
  Start Chat
 
 ';
}

$output .= '';

echo $output;

?>

Here we have create one tag with id="user_details" tag, under this tag it will display user detail table format. For fetch details, here we have make function which send ajax request to fetch_user.php page. This fetch user data and converted into html and send to ajax function which has been display on webpage.

Display Online / Offline User Status in Live chat application

This is next step of How to create chat application in PHP and in this step we have discuss how to display online and offline status of user in real time chat system using PHP Ajax. Because if login can see particular is online then he can chat with online user and he cam make chat conversation with him. For this we want to display particular user status is online or offline. Online user means, user has login into system and he has stay on index.php page. For this we have write following source code for check user is status is online or offline in chat application using PHP.


<!--
//index.php
!-->

<?php

include('database_connection.php');

session_start();

if(!isset($_SESSION['user_id']))
{
 header("location:login.php");
}

?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
  
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
   
    #### Online User

    
Hi -  - [Logout](logout.php "Logout")

    

   
  
      
  







<?php

//update_last_activity.php

include('database_connection.php');

session_start();

$query = "
UPDATE login_details 
SET last_activity = now() 
WHERE login_details_id = '".$_SESSION["login_details_id"]."'
";

$statement = $connect->prepare($query);

$statement->execute();

?>

How To Create Chat App in PHP Using Ajax and JQuery

First on index.php page we have make one function update_last_activity(), this function will ajax request to update_last_activity.php page for update login user last activity datatime details in login_details table. And this function we have called every 5 seconds by using setInterval() jquery method. Under this method we have also add fetch_user() function also. So on every 5 seconds this both function will be called, function will update login user datetime details under login_details table and second function fetch and display updated user details on webpage.


<?php

//database_connection.php

$connect = new PDO("mysql:host=localhost;dbname=chat", "root", "");

date_default_timezone_set('Asia/Kolkata');

function fetch_user_last_activity($user_id, $connect)
{
 $query = "
 SELECT * FROM login_details 
 WHERE user_id = '$user_id' 
 ORDER BY last_activity DESC 
 LIMIT 1
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 foreach($result as $row)
 {
  return $row['last_activity'];
 }
}

?>

After this on database_connection.php page we have make one function fetch_user_last_activity(). This function will fetch particular user last_activity datetime data from login_details table. So, by using this function we can get particular user last activity datetime, so we can check user is online or not in Live Chat App using Ajax with PHP. For this things we have some code at fetch_user.php file. Below you can find that source code.

<?php

//fetch_user.php

include('database_connection.php');

session_start();

$query = "
SELECT * FROM login 
WHERE user_id != '".$_SESSION['user_id']."' 
";

$statement = $connect->prepare($query);

$statement->execute();

$result = $statement->fetchAll();

$output = '

 
  Username
  Status
  Action
 
';

foreach($result as $row)
{
 $status = '';
 $current_timestamp = strtotime(date("Y-m-d H:i:s") . '- 10 second');
 $current_timestamp = date('Y-m-d H:i:s', $current_timestamp);
 $user_last_activity = fetch_user_last_activity($row['user_id'], $connect);
 if($user_last_activity > $current_timestamp)
 {
  $status = 'Online';
 }
 else
 {
  $status = 'Offline';
 }
 $output .= '
 
  '.$row['username'].'
  '.$status.'
  Start Chat
 
 ';
}

$output .= '';

echo $output;

?>

Above code we can see, we have add some code for check particular user is online or offline. For this here first we have store current date time in one variable and and from this datetime we have minus 10 seconds. After this we have store single user last activity datetime has been get by fetch_user_last_activity() and store in one variable. Now we can compare user last activity datetime data with current datetime. If user last activity datetime value greater than current datetime value that means user is login into system and his status will be online and if user last activity datetime value less than current datetime then user status will be offline. So this way we can display user status online or offline in web server based Chat application in PHP.

Make Dynamic Chat Box for Each User in Ajax PHP Chat Application

Now we come to main discussion of PHP Ajax Chat Application and here we have one question how can we generated dynamic chat dialog box for each user. Because this is main part in this via this dialog box user can chat with each other. For this how can we make dynamic chat dialog box for each. For this we have make one jquery function on index.php. This function will dynamically generate html code for chat dialog box. Here for chat dialog box we have use JQuery UI Dialog box plugin. So, when we have called this function this function will generate html code for chat dialog box. Below you can find source code for generating of dynamic chat dialog box.

How To Create Chat App in PHP Using Ajax and JQuery


<!--
//index.php
!-->

<?php

include('database_connection.php');

session_start();

if(!isset($_SESSION['user_id']))
{
 header("location:login.php");
}

?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
  
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
   
    #### Online User

    
Hi -  - [Logout](logout.php "Logout")

    

    

   
  
      
  






In Above source code which we have write index.php page. Here we can see make_chat_dialog_box() function. This function will generate chat dialog box for each user based on value of to_user_id and to_user_name argument. So, based on value of this both argument, this function will make dynamic chat dialog box for every user. Now when this function will be called, this function will be called when we have click on stat chat button. So here we can see jquery code in which we can see start chat button class .start_chat which is selector with click event. So when we have click on this button it will fetch value from data-touserid and data-tousername attribute and store in variable. After this it has called make_chat_dialog_box(to_user_id, to_user_name) function and it will make dynamic chat dialog box for particular user of which we have click on start chat button. So, this way we can make dynamic chat dialog box in our online chat application using PHP.

Insert Chat Message into Mysql Database

Once we have completed learning How can we create dynamic chat dialog box for our chat application in PHP. Now we want to know how can we insert chat message into database and display list of chat message in chat dialog box. So, when we have click on start chat button of any particular user then chat dialog box has been pop up on web page and in that box there is one textarea field in which we chat type chat message and click on send button then chat message will be inserted into database. After insert into database it will display all chat message conversation between two user will be display in chat dialog box without refresh of web page. Because it is a real time chat application which we have made by using PHP with Ajax. Below we can find source code of insert chat message into msyql database.


<!--
//index.php
!-->

<?php

include('database_connection.php');

session_start();

if(!isset($_SESSION['user_id']))
{
 header("location:login.php");
}

?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
  
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
   
    #### Online User

    
Hi -  - [Logout](logout.php "Logout")

    

    

   
  
      
  






How To Create Chat App in PHP Using Ajax and JQuery

Here in index.php page we have write jquery script on send button which class is .send_chat as selector. So when we have click on send button in chat dialog box then it will execute this block of code. In this script we have fetch value of id attribute of this send button in which we have store user id to whom we have send message. After this we have fetch value of textarea in which we have write chat message. After this we have send ajax request to insert_chat.php page for insert chat message into mysql database. This page source code we can find below.

<?php

//insert_chat.php

include('database_connection.php');

session_start();

$data = array(
 ':to_user_id'  => $_POST['to_user_id'],
 ':from_user_id'  => $_SESSION['user_id'],
 ':chat_message'  => $_POST['chat_message'],
 ':status'   => '1'
);

$query = "
INSERT INTO chat_message 
(to_user_id, from_user_id, chat_message, status) 
VALUES (:to_user_id, :from_user_id, :chat_message, :status)
";

$statement = $connect->prepare($query);

if($statement->execute($data))
{
 echo fetch_user_chat_history($_SESSION['user_id'], $_POST['to_user_id'], $connect);
}

?>

Above source code for insert chat message into Mysql table. Here we have make simple insert query using PHP PDO and pass required data for insert into database. After insert into database we want to display all chat message conversation in chat dialog box. So we have to fetch chat data from database which source code we can find below.


<?php

//database_connection.php

$connect = new PDO("mysql:host=localhost;dbname=chat", "root", "");

date_default_timezone_set('Asia/Kolkata');

function fetch_user_last_activity($user_id, $connect)
{
 $query = "
 SELECT * FROM login_details 
 WHERE user_id = '$user_id' 
 ORDER BY last_activity DESC 
 LIMIT 1
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 foreach($result as $row)
 {
  return $row['last_activity'];
 }
}

function fetch_user_chat_history($from_user_id, $to_user_id, $connect)
{
 $query = "
 SELECT * FROM chat_message 
 WHERE (from_user_id = '".$from_user_id."' 
 AND to_user_id = '".$to_user_id."') 
 OR (from_user_id = '".$to_user_id."' 
 AND to_user_id = '".$from_user_id."') 
 ORDER BY timestamp DESC
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 $output = '';
 foreach($result as $row)
 {
  $user_name = '';
  if($row["from_user_id"] == $from_user_id)
  {
   $user_name = 'You';
  }
  else
  {
   $user_name = ''.get_user_name($row['from_user_id'], $connect).'';
  }
  $output .= '
  
   '.$user_name.' - '.$row["chat_message"].'
    
     - *'.$row['timestamp'].'*
    
   
  
  ';
 }
 $output .= '';
 return $output;
}

function get_user_name($user_id, $connect)
{
 $query = "SELECT username FROM login WHERE user_id = '$user_id'";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 foreach($result as $row)
 {
  return $row['username'];
 }
}



?>

For fetch chat conversation we have make fetch_user_chat_history() function in database_connection.php file. This function has fetch latest chat message from mysql database and return data in html format. Here we have make one another function get_user_name() this function has return username of particular user based on value of user_id. So, this two function has use for return chat message in html format and this data has been display under chat dialog box using Ajax. So, this way we have insert chat message into mysql database and then after display in chat dialog box using Ajax with PHP.

How To Create Chat App in PHP Using Ajax and JQuery

Auto Refresh Chat Message in PHP Chat Application

Once chat message has inserted into Mysql database then after we want to display chat message to sender and receiver in their chat history without refresh of web page. For this we have make two jquery function on index.php page. Below you can find source code of it.


<!--
//index.php
!-->

<?php

include('database_connection.php');

session_start();

if(!isset($_SESSION['user_id']))
{
 header("location:login.php");
}

?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
  
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
   
    #### Online User

    
Hi -  - [Logout](logout.php "Logout")

    

    

   
  
      
  





Above we can see we have make two function like fetch_user_chat_history() and update_chat_history_data() function. First function fetch chat data from mysql table and display under chat history div tag of particular user dialog box. After this we have called this function into make_chat_dialog_box(). So when user click on start chat button then it will called make_chat_dialog_box() function for make dynamic chat dialog box and under this function will called fetch_user_chat_history() which fetch chat message of sender and receiver and display under chat dialog box chat history div tag.

For make live and real time chat application we have make update_chat_history_data() function, this function we have use each() jquery method on .chat_history div tag. So this method will fetch data-touserid of each div tag of this class and store under this to_user_id variable and then after it will called fetch_user_chat_history() function based on value of to_user_id variable. So this function will update chat history in all chat dialog box which we have open in web page. For live and real time chat system we have add this update_chat_history_data() function into setInterval() method. So this function will be executed on every 5 seconds and it will update chat history data on every 5 seconds on web page in each user chat dialog box.

<?php

//fetch_user_chat_history.php

include('database_connection.php');

session_start();

echo fetch_user_chat_history($_SESSION['user_id'], $_POST['to_user_id'], $connect);

?>

Above code has been executed when ajax request send request to this page. Here we have simply called fetch_chat_history() function which we have make under database_connection.php. This function will fetch sender and receiver chat data and converted into html format and send to Ajax request.

Make New Message Notification in Chat Application

How To Create Chat App in PHP Using Ajax and JQuery

When sender send chat message to receiver then at receiver web page new message notification must be display and display how many new message he has received. So this feature we have add into this PHP Ajax Chat Application. For this we have make one function in database_connection.php file which source code you can find below.

<?php

//database_connection.php

$connect = new PDO("mysql:host=localhost;dbname=chat", "root", "");

date_default_timezone_set('Asia/Kolkata');

function fetch_user_last_activity($user_id, $connect)
{
 $query = "
 SELECT * FROM login_details 
 WHERE user_id = '$user_id' 
 ORDER BY last_activity DESC 
 LIMIT 1
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 foreach($result as $row)
 {
  return $row['last_activity'];
 }
}

function fetch_user_chat_history($from_user_id, $to_user_id, $connect)
{
 $query = "
 SELECT * FROM chat_message 
 WHERE (from_user_id = '".$from_user_id."' 
 AND to_user_id = '".$to_user_id."') 
 OR (from_user_id = '".$to_user_id."' 
 AND to_user_id = '".$from_user_id."') 
 ORDER BY timestamp DESC
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 $output = '';
 foreach($result as $row)
 {
  $user_name = '';
  if($row["from_user_id"] == $from_user_id)
  {
   $user_name = 'You';
  }
  else
  {
   $user_name = ''.get_user_name($row['from_user_id'], $connect).'';
  }
  $output .= '
  
   '.$user_name.' - '.$row["chat_message"].'
    
     - *'.$row['timestamp'].'*
    
   
  
  ';
 }
 $output .= '';
 $query = "
 UPDATE chat_message 
 SET status = '0' 
 WHERE from_user_id = '".$to_user_id."' 
 AND to_user_id = '".$from_user_id."' 
 AND status = '1'
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 return $output;
}

function get_user_name($user_id, $connect)
{
 $query = "SELECT username FROM login WHERE user_id = '$user_id'";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 foreach($result as $row)
 {
  return $row['username'];
 }
}

function count_unseen_message($from_user_id, $to_user_id, $connect)
{
 $query = "
 SELECT * FROM chat_message 
 WHERE from_user_id = '$from_user_id' 
 AND to_user_id = '$to_user_id' 
 AND status = '1'
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $count = $statement->rowCount();
 $output = '';
 if($count > 0)
 {
  $output = ''.$count.'';
 }
 return $output;
}



?>

Above we can see count_unseen_message() function which get number chat message is unread under chat message table for particular user. Here status '1' means message unread and once message has been read then status will be change to '0'. So this function will count unread message of receiver of partcular sender based on value of status. For change message status we have add update chat message query under fetch_user_chat_history() so when this function will called then it will change chat message to '0'. After this function has been called in fetch_user.php where we have fetch user details. So, it will display new message notification when it has fetch user details. So on every user row it will display any new message notification or not.

<?php

//fetch_user.php

include('database_connection.php');

session_start();

$query = "
SELECT * FROM login 
WHERE user_id != '".$_SESSION['user_id']."' 
";

$statement = $connect->prepare($query);

$statement->execute();

$result = $statement->fetchAll();

$output = '

 
  Username
  Status
  Action
 
';

foreach($result as $row)
{
 $status = '';
 $current_timestamp = strtotime(date("Y-m-d H:i:s") . '- 10 second');
 $current_timestamp = date('Y-m-d H:i:s', $current_timestamp);
 $user_last_activity = fetch_user_last_activity($row['user_id'], $connect);
 if($user_last_activity > $current_timestamp)
 {
  $status = 'Online';
 }
 else
 {
  $status = 'Offline';
 }
 $output .= '
 
  '.$row['username'].' '.count_unseen_message($row['user_id'], $_SESSION['user_id'], $connect).'
  '.$status.'
  Start Chat
 
 ';
}

$output .= '';

echo $output;

?>

Here Above we have called count_unseen_message() function for display any new message notification for every user. If there is any new message notification then it will display new chat message notification otherwise it will not display notification. So this way we can display new message notification in Chat Application by using PHP with Ajax JQuery with Mysql.

Display Typing Notification to Receiver When Sender Start Type

Here we have add one more in out chat application and that is how can we display typing notification to receiver when sender has start type in his chat dialog box. We have mainly seen this type of feature in many social media site. So, here we have also add this functionality in building of chat application using PHP Ajax. For this we have add one table column with name is_type in login_details table with enum('no','yes') datatype. No means user is not type in his chat dialog box and yes means user is start type in his chat dialog box. When user login into chat system then this column value will be no and we will update this column value to yes when user has start write in his chat dialog box.


<!--
//index.php
!-->

<?php

include('database_connection.php');

session_start();

if(!isset($_SESSION['user_id']))
{
 header("location:login.php");
}

?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
  
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
   
    #### Online User

    
Hi -  - [Logout](logout.php "Logout")

    

    

   
  
      
  






How To Create Chat App in PHP Using Ajax and JQuery

First we have on index.php page make_chat_dialog_box() function and in this function we have add .chat_message in the class attribute of textarea field. We will use this class attribute as a selector in jquery script. After this we have use this selector with jquery focus and blur event. Focus event means when cursor come into textarea field then this focus event code will execute at that time is_type variable value is equal to yes and this variable we have send to ajax request for update is_type table column value to yes. And on blur event when cursor leave from textarea field and at that time is_type variable value set to not and send this variable to ajax request for update is_type table column value set to no in PHP script.

<?php

//update_is_type_status.php

include('database_connection.php');

session_start();

$query = "
UPDATE login_details 
SET is_type = '".$_POST["is_type"]."' 
WHERE login_details_id = '".$_SESSION["login_details_id"]."'
";

$statement = $connect->prepare($query);

$statement->execute();

?>

This update_is_type_status.php page has received two ajax request at textarea field focus event and second request on textarea field blur event. In both event request has been send to this page for update value of is_type table column of login_details table. Now we want to fetch when particular user login_details table is_status column value is yes which source code we can find below.

<?php

//database_connection.php

$connect = new PDO("mysql:host=localhost;dbname=chat", "root", "");

date_default_timezone_set('Asia/Kolkata');

function fetch_user_last_activity($user_id, $connect)
{
 $query = "
 SELECT * FROM login_details 
 WHERE user_id = '$user_id' 
 ORDER BY last_activity DESC 
 LIMIT 1
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 foreach($result as $row)
 {
  return $row['last_activity'];
 }
}

function fetch_user_chat_history($from_user_id, $to_user_id, $connect)
{
 $query = "
 SELECT * FROM chat_message 
 WHERE (from_user_id = '".$from_user_id."' 
 AND to_user_id = '".$to_user_id."') 
 OR (from_user_id = '".$to_user_id."' 
 AND to_user_id = '".$from_user_id."') 
 ORDER BY timestamp DESC
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 $output = '';
 foreach($result as $row)
 {
  $user_name = '';
  if($row["from_user_id"] == $from_user_id)
  {
   $user_name = 'You';
  }
  else
  {
   $user_name = ''.get_user_name($row['from_user_id'], $connect).'';
  }
  $output .= '
  
   '.$user_name.' - '.$row["chat_message"].'
    
     - *'.$row['timestamp'].'*
    
   
  
  ';
 }
 $output .= '';
 $query = "
 UPDATE chat_message 
 SET status = '0' 
 WHERE from_user_id = '".$to_user_id."' 
 AND to_user_id = '".$from_user_id."' 
 AND status = '1'
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 return $output;
}

function get_user_name($user_id, $connect)
{
 $query = "SELECT username FROM login WHERE user_id = '$user_id'";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 foreach($result as $row)
 {
  return $row['username'];
 }
}

function count_unseen_message($from_user_id, $to_user_id, $connect)
{
 $query = "
 SELECT * FROM chat_message 
 WHERE from_user_id = '$from_user_id' 
 AND to_user_id = '$to_user_id' 
 AND status = '1'
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $count = $statement->rowCount();
 $output = '';
 if($count > 0)
 {
  $output = ''.$count.'';
 }
 return $output;
}

function fetch_is_type_status($user_id, $connect)
{
 $query = "
 SELECT is_type FROM login_details 
 WHERE user_id = '".$user_id."' 
 ORDER BY last_activity DESC 
 LIMIT 1
 "; 
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 $output = '';
 foreach($result as $row)
 {
  if($row["is_type"] == 'yes')
  {
   $output = ' - *Typing...*';
  }
 }
 return $output;
}



?>

How To Create Chat App in PHP Using Ajax and JQuery

On database_connection.php file we have make one another function for fetch user typing status for this we have make fetch_is_type_status() function. This function will return value if particular user is_type table column value is yes. If any user is_type table column value is yes then we want to display on webpage.


<?php

//fetch_user.php

include('database_connection.php');

session_start();

$query = "
SELECT * FROM login 
WHERE user_id != '".$_SESSION['user_id']."' 
";

$statement = $connect->prepare($query);

$statement->execute();

$result = $statement->fetchAll();

$output = '

 
  Username
  Status
  Action
 
';

foreach($result as $row)
{
 $status = '';
 $current_timestamp = strtotime(date("Y-m-d H:i:s") . '- 10 second');
 $current_timestamp = date('Y-m-d H:i:s', $current_timestamp);
 $user_last_activity = fetch_user_last_activity($row['user_id'], $connect);
 if($user_last_activity > $current_timestamp)
 {
  $status = 'Online';
 }
 else
 {
  $status = 'Offline';
 }
 $output .= '
 
  '.$row['username'].' '.count_unseen_message($row['user_id'], $_SESSION['user_id'], $connect).' '.fetch_is_type_status($row['user_id'], $connect).'
  '.$status.'
  Start Chat
 
 ';
}

$output .= '';

echo $output;

?>

For display sender typing message notification to receiver for this we have called fetch_is_type_status() function in fetch_user.php page along with display of username table column. This page send updated user data on every 5 seconds. So, on every 5 seconds this function will be called and it will display updated status on web page. So, this is the whole process for display sender typing notification on receiver web page. This will add additional functionality in our chat application.

If have learn How to create Chat application in PHP with Ajax JQuery Mysql Bootstrap and Jquery UI from this tutorial. If you have any query into tutorial, please comment your query in comment box. We will reply on that comment and solve any issue in this real time live chat application using PHP Ajax.

Insert Emoji in Chat Message

Here we have add one more feature in PHP Chat application tutorial and this feature is how to insert Emoji in textarea field of chat message and emoji insert into mysql database and fetch emoji from Mysql database and display on web page using PHP with Ajax JQuery. For Insert Emoji into Mysql database, so first we have want to configured our mysql database for insert emoji into database. If we have not configured database then emoji will be converted into special character. For configured Mysql database, so first we have to change collation of Mysql database from default to uft8mb4_bin. For this we have to write following SQL query.

ALTER DATABASE chat CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

Above query will change default of collation of Mysql database to utf8mb4_bin. Same way we want to also change collation of table in which want to store emoji with chat message. For this we have to write below sql query.

ALTER TABLE chat_message CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin

The Above query will change default collation of chat_message table to utf8mb4_bin. This is required for store emoji under Mysql database. After this we want to add character set in database connection also. For this we have to go to database_connection.php file and define character set in database connection string.

<?php

//database_connection.php

$connect = new PDO("mysql:host=localhost;dbname=chat;charset=utf8mb4", "root", "");

How To Create Chat App in PHP Using Ajax and JQuery

So this way we can define character set under database connection string. This way we can configured our Mysql database for insert emoji under Mysql database table. Now we have proceed for how to use emoji in our PHP application. For emoji use in our web application we have use emojioneArea plugin. By using this plugin we can use emoji in our PHP web application. Below you can find index.php file code in which we have integrate emojioneArea plugin.


<!--
//index.php
!-->

<?php

include('database_connection.php');

session_start();

if(!isset($_SESSION['user_id']))
{
 header("location:login.php");
}

?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
        
  
    
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
   
    #### Online User

    
Hi -  - [Logout](logout.php "Logout")

    

    

   
  
      
  





Above we can see how to use emojioneArea plugin, so first we have imported emojioneArea plugin stylesheet and javascript file in above of this page. Now we want to initialize emojioneArea plugin on textarea field of chat dialog box in which we have type chat message. So, in jquery code on .start_chat click event and in this we have initialize emojioneArea plugin by using emojioneArea() method. This method will initialize this plugin when we have click on start chat button then this plugin will activate and we can on textarea field. After send of message we want to clear textarea field text with emoji, so we have use use emojioneArea.setText(''), by using this method we can clear emoji with text from textarea field. So this way we can use emoji in our PHP Chat application.

Group Chat

This simple one to one chat application which we have build still, but now we have add Group Chat feature also in Chat System. By using Group chat all user can communicate with each other in one single place at the same time and all user can see message of all user in Group Chat window. So, Below you can find step by step source of Group Chat which we have integrate in our exisiting chat application.



<!--
index.php
!-->


 

 
 
  
 
 
  Send
 

How To Create Chat App in PHP Using Ajax and JQuery

Here first we have make Group Chat dialog box by using Jquery UI dialog plugin which source code you have find above in index.php file.

<!--
index.php
!-->

$('#group_chat_dialog').dialog({
 autoOpen:false,
 width:400
});

This code will activate jQuery UI dialog plugin on #group_chat_dialog div tag and autoOpen option set to false means it will not pop up dialog box on page load.

<!--
index.php
!-->


Group Chat

Here we have define one button, when we have click on group_chat button then we want to pop up Group Chat dialog box on web page. Here we have also define one hidden field with id = is_active_group_chat_window. This field value we have set to no that means Group chat dialog box is not open on web page. This field value will be change to yes if Group chat has been pop up on web page.

<!--
index.php
!-->

$('#group_chat').click(function(){
 $('#group_chat_dialog').dialog('open');
 $('#is_active_group_chat_window').val('yes');
 fetch_group_chat_history();
});

For pop up group chat dialog box we have write above jquery code on button with id=group_chat. For pop up group chat dialog box we have use .dialog('open') method. After pop up of group chat box we have change hidden field value to 'yes' and here we have called fetch_group_chat_history() function which will fetch group chat message and display under group chat dialog box. This function source code you can find below.



<!--
index.php
!-->

$('#send_group_chat').click(function(){
 var chat_message = $('#group_chat_message').val();
 var action = 'insert_data';
 if(chat_message != '')
 {
  $.ajax({
   url:"group_chat.php",
   method:"POST",
   data:{chat_message:chat_message, action:action},
   success:function(data){
    $('#group_chat_message').val('');
    $('#group_chat_history').html(data);
   }
  })
 }
});

How To Create Chat App in PHP Using Ajax and JQuery

Above code is for insert chat message into Group chat. For this here we have use Ajax request, by using Ajax request we have send request to PHP script for insert chat message into Mysql table. Here we have send request to group_chat.php file.

<!--
index.php
!-->

function fetch_group_chat_history()
{
 var group_chat_dialog_active = $('#is_active_group_chat_window').val();
 var action = "fetch_data";
 if(group_chat_dialog_active == 'yes')
 {
  $.ajax({
   url:"group_chat.php",
   method:"POST",
   data:{action:action},
   success:function(data)
   {
    $('#group_chat_history').html(data);
   }
  })
 }
}

For fetch all group chat message here we have make one jquery function which use Ajax request for fetch Group chat message from Mysql database and display under Group Chat dialog box. Here also ajax request has been send to group_chat.php file.

<?php

//group_chat.php

include('database_connection.php');

session_start();

if($_POST["action"] == "insert_data")
{
 $data = array(
  ':from_user_id'  => $_SESSION["user_id"],
  ':chat_message'  => $_POST['chat_message'],
  ':status'   => '1'
 );

 $query = "
 INSERT INTO chat_message 
 (from_user_id, chat_message, status) 
 VALUES (:from_user_id, :chat_message, :status)
 ";

 $statement = $connect->prepare($query);

 if($statement->execute($data))
 {
  echo fetch_group_chat_history($connect);
 }

}

if($_POST["action"] == "fetch_data")
{
 echo fetch_group_chat_history($connect);
}

?>

This is source code of group_chat.php file. Here we have perform two database operation. If $_POST["action"] == 'insert_data', then that block of code will insert group chat message into Mysql table and if $_POST["action"] == 'fetch_data' then that block of code will fetch all group chat message from Mysql database. For fetch group chat message we have make one php function like fetch_group_chat_history($connect) in database_connection.php file.

<?php

//database_connection.php

function fetch_group_chat_history($connect)
{
 $query = "
 SELECT * FROM chat_message 
 WHERE to_user_id = '0'  
 ORDER BY timestamp DESC
 ";

 $statement = $connect->prepare($query);

 $statement->execute();

 $result = $statement->fetchAll();

 $output = '';
 foreach($result as $row)
 {
  $user_name = '';
  if($row["from_user_id"] == $_SESSION["user_id"])
  {
   $user_name = 'You';
  }
  else
  {
   $user_name = ''.get_user_name($row['from_user_id'], $connect).'';
  }

  $output .= '

  
   '.$user_name.' - '.$row['chat_message'].' 
    
     - *'.$row['timestamp'].'*
    
   
  
  ';
 }
 $output .= '';
 return $output;
}

?>

Above source code is from database_connection.php file php function fetch_group_chat_history($connect). This function return fetch all group chat message.


<!--

index.php

!-->

setInterval(function(){
 update_last_activity();
 fetch_user();
 update_chat_history_data();
 fetch_group_chat_history();
}, 5000);

For make group chat in real time then we have called jquery fetch_group_chat_history() function in setInterval() method in which fetch_group_chat_history() run on every 5 seconds and it will make Group chat feature in real time. So, this is step by step process of integrate Group chat feature in our exisiting chat application which has been made by using PHP with Ajax Jquery, Mysql and Bootstrap.

Image Share in Group Chat

How To Create Chat App in PHP Using Ajax and JQuery

After making Group Chat feature in Chat App, now we have add one more feature like image share in exisiting Chat application. So, Group user can share image in Group and that image can view by all member. For share image we have use Jquery Form plugin, by using this plugin we can share image in Group chat. Same way we have replace textarea field with editable div tag by using contenteditable attribute. By using this attribute we can make editable div tag for type chat message. And under this tag we will display uploaded image, so user can type message with image also. And by click on send button group member can share image in Group which will be visible to all member of group. Below you can find source code of How to share image in group chat of Chat application.


<!--
//index.php
!-->

<?php

include('database_connection.php');

session_start();

if(!isset($_SESSION['user_id']))
{
 header("location:login.php");
}

?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
        
  
    
    
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
    
     #### Online User

    
    
     
     Group Chat
    
    
     
Hi -  - [Logout](logout.php "Logout")

    
   
   
    
    

    

   
  
      


  


 

 
 
  !-->
  
   

   
   
    
     ![](upload.png)
     
    
   
  
 
 
  Send
 





<?php

//upload.php

if(!empty($_FILES))
{
 if(is_uploaded_file($_FILES['uploadFile']['tmp_name']))
 {
  $_source_path = $_FILES['uploadFile']['tmp_name'];
  $target_path = 'upload/' . $_FILES['uploadFile']['name'];
  if(move_uploaded_file($_source_path, $target_path))
  {
   echo '
![]()

';
  }
 }
}

?>

Download

Remove individual Chat Message

In this Ajax PHP Chat system we have add one more feature like how can user can remove their chat message from One to one chat. So, here we have add this functionality, so from chat from two person, sender user can remove his chat from chat history. In many social medial website we can see this type of feature. This feature is required, if user chat some mistake in chat message and post that message. This type of message can be removed by sender user. So that message will not be visible to receiver user.

How To Create Chat App in PHP Using Ajax and JQuery

For make this type of functionality under this system, first we have to put remove button with chat message. In this system in database_connection.php file, we have make one function fetch_user_chat_history(). This function has return chat history create between to user. In this function we have add remove chat message button. By click on this button particular user can remove his or her chat message. Below this you can find updated PHP code for fetch_user_chat_history() function.

database_connection.php

<?php

function fetch_user_chat_history($from_user_id, $to_user_id, $connect)
{
 $query = "
 SELECT * FROM chat_message 
 WHERE (from_user_id = '".$from_user_id."' 
 AND to_user_id = '".$to_user_id."') 
 OR (from_user_id = '".$to_user_id."' 
 AND to_user_id = '".$from_user_id."') 
 ORDER BY timestamp DESC
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 $output = '';
 foreach($result as $row)
 {
  $user_name = '';
  $dynamic_background = '';
  $chat_message = '';
  if($row["from_user_id"] == $from_user_id)
  {
   if($row["status"] == '2')
   {
    $chat_message = '*This message has been removed*';
    $user_name = 'You';
   }
   else
   {
    $chat_message = $row['chat_message'];
    $user_name = 'x You';
   }
   

   $dynamic_background = 'background-color:#ffe6e6;';
  }
  else
  {
   if($row["status"] == '2')
   {
    $chat_message = '*This message has been removed*';
   }
   else
   {
    $chat_message = $row["chat_message"];
   }
   $user_name = ''.get_user_name($row['from_user_id'], $connect).'';
   $dynamic_background = 'background-color:#ffffe6;';
  }
  $output .= '
  
   '.$user_name.' - '.$chat_message.'
    
     - *'.$row['timestamp'].'*
    
   
  
  ';
 }
 $output .= '';
 $query = "
 UPDATE chat_message 
 SET status = '0' 
 WHERE from_user_id = '".$to_user_id."' 
 AND to_user_id = '".$from_user_id."' 
 AND status = '1'
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 return $output;
}

?>

Once remove chat button come with Chat history. After this we have to write Ajax Jquery code for send change status of particular chat message. So, on index.php we have write jQuery code, so when user click on remove chat button then this code will execute and this code will send ajax request to remove_chat.php file for change particular chat message status.

index.php

$(document).on('click', '.remove_chat', function(){
  var chat_message_id = $(this).attr('id');
  if(confirm("Are you sure you want to remove this chat?"))
  {
   $.ajax({
    url:"remove_chat.php",
    method:"POST",
    data:{chat_message_id:chat_message_id},
    success:function(data)
    {
     update_chat_history_data();
    }
   })
  }
 });

remove_chat.php

<?php

//remove_chat.php

include('database_connection.php');

if(isset($_POST["chat_message_id"]))
{
 $query = "
 UPDATE chat_message 
 SET status = '2' 
 WHERE chat_message_id = '".$_POST["chat_message_id"]."'
 ";

 $statement = $connect->prepare($query);

 $statement->execute();
}

?>

In above code we can see on index.php file we have add one more jQuery code for give action to remove chat button and in that code we have send Ajax request to remove_chat.php file for change status of chat message based on id value of chat message. This is whole process for add remove chat functionality in Live chat application using PHP Ajax jQuery and Mysql.

Remove Chat Message from Group Chat

After remove chat message from one to one chat history, then after in Chat Application, here we have add one more functionality like remove chat message from Group chat history also. Suppose user want to remove his chat message which he has post in Group then he can remove by using this feature. He can not only remove their message but also he can also remove image which he share into Group.

How To Create Chat App in PHP Using Ajax and JQuery

For implement this feature in existing Chat application we do not want to make huge changes in our existing PHP and jQuery code. First we do not want make any changes in index.php file. Which ever we have write jQuery code on .remove_chat button class, that code here we will also use for remove chat message from Group Chat history.

But we have make required changes in database_connection.php file fetch_group_chat_history(), because this function return Group chat history. So we have to make some changes under this function. Under this function we have to add remove chat button with chat message and this button must be visible to only that user who has share chat under group. Below you can find changes under function for fetch fetch group chat history.

database_connection.php

<?php

function fetch_group_chat_history($connect)
{
 $query = "
 SELECT * FROM chat_message 
 WHERE to_user_id = '0'  
 ORDER BY timestamp DESC
 ";
 $statement = $connect->prepare($query);
 $statement->execute();
 $result = $statement->fetchAll();
 $output = '';
 foreach($result as $row)
 {
  $user_name = '';
  $chat_message = '';
  $dynamic_background = '';

  if($row['from_user_id'] == $_SESSION['user_id'])
  {
   if($row["status"] == '2')
   {
    $chat_message = '*This message has been removed*';
    $user_name = 'You';
   }
   else
   {
    $chat_message = $row['chat_message'];
    $user_name = 'x You';
   }
   $dynamic_background = 'background-color:#ffe6e6;';
  }
  else
  {
   if($row["status"] == '2')
   {
    $chat_message = '*This message has been removed*';
   }
   else
   {
    $chat_message = $row['chat_message'];
   }
   $user_name = ''.get_user_name($row['from_user_id'], $connect).'';
   $dynamic_background = 'background-color:#ffffe6;';
  }
  $output .= '
  
   '.$user_name.' - '.$chat_message.' 
    
     - *'.$row['timestamp'].'*
    
   
   
  
  ';
 }
 $output .= '';
 return $output;
}

?>
Registration in Chat application using PHP

Now our chat system core part is ready, so we want to make this system dynamic. That means new user can register into chat system and take part into chat with other member or group chat. For this we add new feature like new user registration in this PHP Ajax Chat application. By using this feature new use can register into this chat system and login into system and use this chat application different functionality like one to chat or group chat. This new register user can chat all member who has register into this system.

How To Create Chat App in PHP Using Ajax and JQuery

For make registration form for this chat application we have use simple HTML for front end and for backend we have use PHP script. Below you can find complete source code for Chat application registration using PHP.

register.php

<!--
//register.php
!-->

<?php

include('database_connection.php');

session_start();

$message = '';

if(isset($_SESSION['user_id']))
{
 header('location:index.php');
}

if(isset($_POST["register"]))
{
 $username = trim($_POST["username"]);
 $password = trim($_POST["password"]);
 $check_query = "
 SELECT * FROM login 
 WHERE username = :username
 ";
 $statement = $connect->prepare($check_query);
 $check_data = array(
  ':username'  => $username
 );
 if($statement->execute($check_data)) 
 {
  if($statement->rowCount() > 0)
  {
   $message .= '
Username already taken
';
  }
  else
  {
   if(empty($username))
   {
    $message .= '
Username is required
';
   }
   if(empty($password))
   {
    $message .= '
Password is required
';
   }
   else
   {
    if($password != $_POST['confirm_password'])
    {
     $message .= '
Password not match
';
    }
   }
   if($message == '')
   {
    $data = array(
     ':username'  => $username,
     ':password'  => password_hash($password, PASSWORD_DEFAULT)
    );

    $query = "
    INSERT INTO login 
    (username, password) 
    VALUES (:username, :password)
    ";
    $statement = $connect->prepare($query);
    if($statement->execute($data))
    {
     $message = "Registration Completed";
    }
   }
  }
 }
}

?>

  
      
        Chat Application using PHP Ajax Jquery  
  
        
  
    
      
      
        
   

   
   ### Chat Application using PHP Ajax Jquery


   

   
      Chat Application Register

    
     
      
      
       Enter Username
       
      
      
       Enter Password
       
      
      
       Re-enter Password
       
      
      
       
      
      
       [Login](login.php "Login")
      
     
    
   
  
      

So, here in this chat application most of the feature has been covered and it is ready for any small project which has been use for any colleage project. If you have any new feature which has been required to add into this system, you can comment into comment box.

How To Create Chat App in PHP Using Ajax and JQuery