Angular

Datatables Plugin in Angular 7 Using .NET Core Web API Part One

Here, we will learn about how can we integrate the datatable plugin with server-side pagination, sorting and searching. As it is the basic requirement for all the web application to display the data. So client side pagination is not good.

Why Server Side Pagination?

Server side pagination is very useful for the web application to handle the data by the client is very small than the actual data exist in the server. The data are loaded on a demand basis.

Prerequisite

  • Knowledge of .NET Core Web API
  • Basic knowledge of Angular 7
  • Node JS must be installed
  • Angular CLI must be installed

This article will be covered in two parts. Part-1 contains the backend logic and Part-2 contains frontend development.

So, let’s get started building our backend application

Create a new project. We are going to use the code first approach for it.

Add a new folder as Entity and Create a Context.cs file inside the folder and add the code in it.

using Microsoft.EntityFrameworkCore;

namespace AngularDatatable.Entity
{
    public class Context : DbContext
    {
        public Context(DbContextOptions<Context> options) : base(options) { }
        public DbSet<Users> Users { get; set; }
    }
}

Create Users.cs file and add the code in it.

using System.ComponentModel.DataAnnotations;

namespace AngularDatatable.Entity
{
    public class Users
    {
        [Key]
        public int ID { get; set; }

        public string Name { get; set; }

        public string Email { get; set; }

        public string Company { get; set; }

        public string ContactNumber { get; set; }
    }
}

Now in the Models folder create below class files as Column, Order, PagingRequest, PagingRequest, Search and SearchCriteria respectively.

Code for Column.cs file

using Newtonsoft.Json;

namespace AngularDatatable.Models
{
    public class Column
    {
        [JsonProperty(PropertyName = "data")]
        public string Data { get; set; }

        [JsonProperty(PropertyName = "name")]
        public string Name { get; set; }

        [JsonProperty(PropertyName = "searchable")]
        public bool Searchable { get; set; }

        [JsonProperty(PropertyName = "orderable")]
        public bool Orderable { get; set; }

        [JsonProperty(PropertyName = "search")]
        public Search Search { get; set; }
    }
}

Code for Order.cs file

using Newtonsoft.Json;

namespace AngularDatatable.Models
{
    public class Order
    {
        [JsonProperty(PropertyName = "column")]
        public int Column { get; set; }

        [JsonProperty(PropertyName = "dir")]
        public string Dir { get; set; }
    }
}

Code for PagingRequest.cs file

using Newtonsoft.Json;
using System.Collections.Generic;

namespace AngularDatatable.Models
{
    public class PagingRequest
    {
        [JsonProperty(PropertyName = "draw")]
        public int Draw { get; set; }

        [JsonProperty(PropertyName = "columns")]
        public IList<Column> Columns { get; set; }

        [JsonProperty(PropertyName = "order")]
        public IList<Order> Order { get; set; }

        [JsonProperty(PropertyName = "start")]
        public int Start { get; set; }

        [JsonProperty(PropertyName = "length")]
        public int Length { get; set; }

        [JsonProperty(PropertyName = "search")]
        public Search Search { get; set; }

        [JsonProperty(PropertyName = "searchCriteria")]
        public SearchCriteria SearchCriteria { get; set; }
    }
}

Code for PagingResponse.cs file

using AngularDatatable.Entity;
using Newtonsoft.Json;

namespace AngularDatatable.Models
{
    public class PagingResponse
    {
        [JsonProperty(PropertyName = "draw")]
        public int Draw { get; set; }

        [JsonProperty(PropertyName = "recordsFiltered")]
        public int RecordsFiltered { get; set; }

        [JsonProperty(PropertyName = "recordsTotal")]
        public int RecordsTotal { get; set; }

        [JsonProperty(PropertyName = "data")]
        public Users[] Users { get; set; }
    }
}

Code for Search.cs file

using Newtonsoft.Json;

namespace AngularDatatable.Models
{
    public class Search
    {
        [JsonProperty(PropertyName = "value")]
        public string Value { get; set; }

        [JsonProperty(PropertyName = "regex")]
        public bool Regex { get; set; }
    }
}

Code for SearchCriteria.cs file

using Newtonsoft.Json;

namespace AngularDatatable.Models
{
    public class SearchCriteria
    {
        [JsonProperty(PropertyName = "filter")]
        public string Filter { get; set; }

        [JsonProperty(PropertyName = "isPageLoad")]
        public bool IsPageLoad { get; set; }
    }
}

Add a new Api Controller as DatatableApiController and add the code in it.

using System.Linq;
using AngularDatatable.Entity;
using AngularDatatable.Models;
using Microsoft.AspNetCore.Mvc;

namespace AngularDatatable.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class DatatableApiController : ControllerBase
    {
        private readonly Context _context;
        public DatatableApiController(Context context)
        {
            _context = context;
        }
        [HttpGet]
        public IActionResult Get()
        {
            var users = _context.Users.ToList();
            return Ok(users);
        }
        [HttpPost]
        public IActionResult Get(int id)
        {
            var recordSkip = id == 1 ? 0 : (id - 1) * 10;
            var users = _context.Users.OrderBy(emp => emp.ID).Skip(recordSkip).Take(10).ToList();
            return Ok(users);
        }
        [HttpPut]
        public IActionResult Post([FromBody]PagingRequest paging)
        {
            var pagingResponse = new PagingResponse()
            {
                Draw = paging.Draw
            };

            if (!paging.SearchCriteria.IsPageLoad)
            {
                IQueryable<Users> query = null;

                if (!string.IsNullOrEmpty(paging.SearchCriteria.Filter))
                {
                    query = _context.Users.Where(emp => emp.Name.Contains(paging.SearchCriteria.Filter));
                }
                else
                {
                    query = _context.Users;
                }

                var recordsTotal = query.Count();

                var colOrder = paging.Order[0];

                switch (colOrder.Column)
                {
                    case 0:
                        query = colOrder.Dir == "asc" ? query.OrderBy(emp => emp.ID) : query.OrderByDescending(emp => emp.ID);
                        break;
                    case 1:
                        query = colOrder.Dir == "asc" ? query.OrderBy(emp => emp.Name) : query.OrderByDescending(emp => emp.Name);
                        break;
                    case 2:
                        query = colOrder.Dir == "asc" ? query.OrderBy(emp => emp.Email) : query.OrderByDescending(emp => emp.Email);
                        break;
                    case 3:
                        query = colOrder.Dir == "asc" ? query.OrderBy(emp => emp.Company) : query.OrderByDescending(emp => emp.Company);
                        break;
                }

                pagingResponse.Users = query.Skip(paging.Start).Take(paging.Length).ToArray();
                pagingResponse.RecordsTotal = recordsTotal;
                pagingResponse.RecordsFiltered = recordsTotal;
            }

            return Ok(pagingResponse);
        }
    }
}

Now finally in the startup.cs file make the changes for allowing the angular application to use the API.

Code for StartUp.cs file.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AngularDatatable.Entity;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Serialization;

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

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddJsonOptions(options =>
            {
                var resolver = options.SerializerSettings.ContractResolver;
                if (resolver != null)
                    (resolver as DefaultContractResolver).NamingStrategy = null;
            });
            services.AddDbContext<Context>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DevConnection")));
            services.AddCors();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseCors(options =>
            options.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader());
            app.UseMvc();
        }
    }
}

We will continue the frontend development in Part 2 of this article.

Faisal Pathan

Faisal Pathan is a founder of TheCodeHubs, .NET Project Manager/Team Leader, and C# Corner MVP. He has extensive experience with designing and developing enterprise-scale applications. He has good skills in ASP.NET C#, ASP.NET Core, ASP.NET MVC, AngularJS, Angular, React, NodeJS, Amazon S3, Web API, EPPlus, Amazon MWS, eBay Integration, SQL, Entity Framework, JavaScript, eCommerce Integration like Walmart, Tanga, Newegg, Group-on Store, etc. and Windows services.

View Comments

  • Great blog here! Also your site loads up fast! What web host are you using? Can I get your affiliate link to your host? I wish my website loaded up as fast as yours lol

  • I have been exploring for a bit for any high quality articles or weblog posts in this sort of space . Exploring in Yahoo I at last stumbled upon this website. Studying this information So i am glad to show that I have a very excellent uncanny feeling I discovered exactly what I needed. I such a lot for sure will make sure to don抰 omit this website and give it a look on a relentless basis.

  • Thank you for sharing superb informations. Your web site is very cool. I am impressed by the details that you抳e on this website. It reveals how nicely you understand this subject. Bookmarked this web page, will come back for more articles. You, my pal, ROCK! I found just the information I already searched everywhere and just could not come across. What an ideal web site.

Share
Published by
Faisal Pathan

Recent Posts

Testing hk

Testing

2 years ago

Create and Used PIPE in angular

In this article, we have to show Create and Used PIPE in angular

2 years ago

Operation

Testing

2 years ago

Create and Used PIPE in angular

In this article, we have to show Create and Used PIPE in angular

2 years ago

Create and Used PIPE in angular

In this article, we have to show Create and Used PIPE in angular

2 years ago

TETS NEW

test

2 years ago