Consume Web API in Asp.Net MVC

by Sachin Singh


Posted on Saturday, 19 December 2020

Tags: Perform CRUD with EF in Asp.Net Web API consume web api HttpClient in Web API and MVC

There are multiple ways to consume Web API methods into an Asp.Net MVC Application. For example ,we can directly call a web API method from our Asp.Net MVC controller using HttpClient or RestClient or we can Call a web API Method through Jquery Ajax from Asp.Net MVC view.

Consume Web API into MVC
Consume Web API in MVC

In order to understand the concept completely , definitely, we need to create a web API and an MVC application as a client which will consume the web API methods.

After reading this article two to three times, yes you are right you need to go through the article at least 2 times , you will learn following concepts:-
  • how to consume web API Get method into an MVC Application.
    • how to consume web API POST method into an MVC Application.
    • how to consume web API Put method into an MVC Application.
    • how to consume web API Delete method into an MVC Application.
    • How to Create a web API for Crud operation.
    • Add, Edit, Update and Delete operations using Jquery DataTable and Bootstrap Modal.

Step 1.Create a Database and a Table.

Open SQL Server Management Studio and copy-paste below scripts and execute. The script creates:-
  1. Test Database.
  2. Employee table under Test Database.


  Create Database Test
  Go
  Use Test
   Go
  CREATE TABLE [dbo].[Employee] (
    [Id]     INT          IDENTITY (1, 1) NOT NULL,
    [Name]   VARCHAR (50) NULL,
    [Salary] INT          NULL,
    CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED ([Id] ASC)
   );
   Go

  SET IDENTITY_INSERT [dbo].[Employee] ON
  INSERT INTO [dbo].[Employee] ([Id], [Name], [Salary]) VALUES (1, N'sachin', 100000)
  INSERT INTO [dbo].[Employee] ([Id], [Name], [Salary]) VALUES (2, N'arjun', 23000)
  INSERT INTO [dbo].[Employee] ([Id], [Name], [Salary]) VALUES (3, N'vikash', 30000)
  INSERT INTO [dbo].[Employee] ([Id], [Name], [Salary]) VALUES (4, N'pocha', 43000)
  INSERT INTO [dbo].[Employee] ([Id], [Name], [Salary]) VALUES (5, N'Nivedita', 24000)
  SET IDENTITY_INSERT [dbo].[Employee] OFF
  Go

Step 2.Create a new Asp.Net Web API project.
  • Open Visual Studio , select File--New--Project.

Create Web API Project Step 1
Creating web api project (1)

  • Under installed Template select " Visual C#" and from the middle pane select "Asp.Net Web Application", name the project "MyFirstAPIProject" and Click Ok.
Create Web API Project Step 1.1
Creating web api project (1.1)

  • On the next window, select "Empty template" and check "MVC" checkbox. And Click Ok.
Create Web API Project Step 1.3
Creating web api project (1.3)

  At this point, we have an Empty Web API project created.

Step 3.Add Ado.Net Entity Data Model .

If you have ever worked in any professional web project ,then you may be aware of the term n-tier architecture. Here ,I am not going to discuss the n-tier architecture ,but recommend you to always generate your Entity Data Model in separate Layer ,as this Layer will be responsible for interacting with your database ,so you can call it as Data Access Layer or DAL.

  • Right click on "MyFirstAPIProject" solution in the Solution Explorer and select Add - New Project.

Create Web API Project Step 2
Creating web api project (2.1)

  • In the Add New Project window ,Select Visual C# from the left pane and Class Library Project from the Middle pane and Name the project DAL and click OK .
Create Web API Project Step 2.2
Creating web api project (2.2)

  • Right-click on the DAL project and select Add--New Item.
  • In the "Add New Item" window ,Select "Data" from the left pane, Select ADO.NET Entity Data Model from the middle pane, In the Name text box, type TestModel and click Add.
Create Web API Project Step 2.3
Creating web api project (2.3)

  • On the Entity Data Model Wizard, select "EF Designer from database" option and click next.
Create Web API Project Step 2.4
Creating web api project (2.4)
Create Web API Project Step 2.4.1
Creating web api project (2.4.1)

  • On "Connection Properties" window, set Server Name = (your server name), Authentication = Windows Authentication, Select or enter a database name = Test, Click OK .
  • In the next window , change the TestEntity to TestDbContext and click next.
  • On the next screen, select "Employee" table and click Finish.
Create Web API Project Step 2.5
Creating web api project (2.5)

Step 4. Give reference of DAL to MyFirstAPIProject (web Api project).
  • Right click on the references folder in the MyFirstAPIProject project and select "Add Reference".
  On the "Reference Manager" screen select "DAL" project and click OK.

Create Web API Project Step 4.1
Creating web api project (3.1)

Step 5.Create a controller named Employee Controller. Now, We are ready to write Code for each of the CRUD methods.

Implement Get Method


      public IEnumerable<Employee> GetAllEmployee()
        {
            using(TestDBContext db=new TestDBContext()){
                return db.Employees.ToList();
            }
        }

       public Employee GetEmployeeById(int id)
        {
            using (TestDBContext db = new TestDBContext())
            {
                return db.Employees.FirstOrDefault(e => e.Id == id);
            }
        }

Step 4.Run the application ,and Enter the URL:-
1. http://localhost:portNo/api/employee
It will return the below representation.

Create Empty Web API project
XML representation for all employee

2. http://localhost:portNo/api/employee/4
It will return the below represntation.

Create Empty Web API project
XML representation for particular employee

So, we have successfully Implemented the Get method

Now Let's dive deep and check whether have we followed the rest principles or not.

1.Everything is resource.(No need to verify ,yes everything is a resource. here EmployeeList and single employee both are resource on server).

2.Each resource is uniquely identifiable.(verified)
For List of Employee we have :- http://localhost:portNo/api/employee
For single Employee we have :- http://localhost:portNo/api/employee/1

3.Interface must be simple.(yes ,verified.)
as our method names are starting with Get prefix so the URL are simple. And request is mapping with appropriate action method .The question is how will we achieve simpler interface when method names do not start with http verb.

4.Stateless(verified, over http ,no doubt)

5.Response must be a representation.(yes, verified)
we are getting XML representation back. But how???? who is doing that. we solved the puzzle in previous article.

Is everything good? yes, almost. We are following rest principles obediently. But almost doesn't mean everything.

Let's see what are we missing.

case 1.what if List of employee gets null.(we must return http status code 204 (No content) with no employee found message)

case 2.what if any run time error occurs.(we must return 500 internal server error).

case 3.what if there is no employee of specified Id exist.( we must return 204 status code, with no employee with specified Id exist message. )

In short ,No we are not following rest principles completely. Rest means respect the http protocol and utilize it as much as you can.

Lets modify the above code to get the desired outcome and fulfill the rest principles completely.


  public HttpResponseMessage GetAllEmployee()
        {
            try
            {
                using (TestDBContext db = new TestDBContext())
            {
                var Employees =db.Employees.ToList();
                if(Employees!=null){
                     return Request.CreateResponse(HttpStatusCode.OK, Employees);
                }
               return Request.CreateErrorResponse(HttpStatusCode.NotFound,"No result found");
          }
            }
            catch{
                return new HttpResponseMessage(HttpStatusCode.InternalServerError);
            }
           
        }

        public HttpResponseMessage GetEmployeeById(int Id)
        {
            try
            {	
     using (TestDBContext db = new TestDBContext())
            {

                 Employee emp = db.Employees.Where(x => x.Id == Id).SingleOrDefault();
                if(emp!=null){
                    return Request.CreateResponse(HttpStatusCode.OK,emp);
                }
                return Request.CreateErrorResponse(HttpStatusCode.NotFound,"Employee with id " +Id+ "Not found");
              
            }
     }
            catch
            {
                return new HttpResponseMessage(HttpStatusCode.InternalServerError);
            }
                 
        }

Now ,Run the application and request employee who doesn't exist like employee with id 5. you will get below representation.

Create Empty Web API project
No Result found Error representation

Now Everything is fine. Hurrah ,you have learnt how to create Get Method with Web API.

Now onwards ,I am not going to discuss the rest principles every time. But I am giving you a mantra(Tip).While creating any method in web API ,keep in mind one thing only, that is ,you have to respect the http. Respecting Http means keep the method names simpler or use Http verbs as attribute over action methods and utilize the features of http like setting the useful response headers like http status code, Content-Type, Location of newly created response etc.

Implementing Post Request


  public void Post([FromBody] Employee employee)
        {
            using(TestDBContext db=new TestDBContext()){
                db.Employees.Add(employee);
                db.SaveChanges();
            }
        }

Note:- The Employee object is being passed as parameter to the Post method. The Employee parameter is decorated with [FromBody] attribute. This tells to the Web API to get employee data from the request body.

At this point build the solution. Fireup Fiddler and issue a Post request
  1. Set the HTTP verb to POST
  2. Content-Type: application/json. The content-type tells about the media-type of data being sent to the Web API, in our case, Json data is being send to the server
  3. In the Request Body, include the employee object that you want to add to the database in JSON format
  4. Finally click execute.

Issuing Post Request with fiddler
Issuing Post Request with fiddler

Although this works as expected and adds the Employee data to the database, But, Do you think everything is fine ?Remember what I had pointed out in get implementation, respect the http. So, what are the problems?
  • Since the return type of the Post() method is void, we get status code of 204 No Content. When a new item is created, we should actually be returning status code 201 Item Created.
  • With 201 status code we should also include the location i.e URI of the newly created item.

To achieve this, change the implementation of the Post() as shown below.


  public HttpResponseMessage Post([FromBody] Employee employee)
    {
      try
       {
           using (TestDBContext db = new TestDBContext())
        {
            db.Employees.Add(employee);
            db.SaveChanges();

            var message = Request.CreateResponse(HttpStatusCode.Created, employee);
            message.Headers.Location = new Uri(Request.RequestUri + "/"+
                employee.Id.ToString());

            return message;
        }
    }
    catch (Exception ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
    }
  }

Now is the time to issue another Post request. Notice, this time we are getting 201 status code that implies resource created, along with the URI of newly created resource in the location header

Response Header of Post request
Response Header of Post Request

Implementing Put Method


  public void Put(int id, [FromBody]Employee employee)
  {
     using (TestDBContext db = new TestDBContext())
     {
         Employee emp = db.Employees.FirstOrDefault(e => e.Id == id);

         emp.Name = employee.Name;
         emp.Salary = employee.Salary;
         db.SaveChanges();
     }
   }

Note:-we are passing both the Id of the Employee we want to update and the employee object which contains the updated information and sending which are being sent through response body, Employee parameter is decorated with [FromBody] attribute. The [FromBody] attribute tells the web API to get data from the request body.

At this point build the solution. Fire-up Fiddler and issue a Put request.
  1. Set the HTTP verb to PUT
  2. Content-Type: application/JSON. This tells the web API about the media type of data being sent so that the web API would select the appropriate media-type formatter for parsing.
  3.Construct the data with which you want to update the employee and include that in the request body.
  4. Finally click execute

Firing Put Request
Firing put request with fiddler

This works fine and updates the employee record in the database as expected. But again we have these problems.
  • Since the return type of the Put() method is void, we get a status code of 204 No Content. When the update is successful, we should return status code 200 OK indicating that the update is successful.
  • If the issued Id doesn't exist then we get the status code "500 internal server error" as the response from web API, the reason behind getting status code 500 internal server error is the absence of data which causes null reference exception. But, we should return the "404 Not Found status code " stating employee with such id has not been found to update.

To fix, both of these issues, modify the code in Put() method as shown below.


  public HttpResponseMessage Put(int id, [FromBody]Employee employee)
   {
     try
     {
         using (TestDbContext db = new TestDbContext())
         {
             Employee emp = db.Employees.FirstOrDefault(e => e.Id == id);
             if (emp == null)
             {
                 return Request.CreateErrorResponse(HttpStatusCode.NotFound,
                     "Employee with Id " + id.ToString() + " not found to update");
             }
             else
             {
                 emp.Name = employee.Name;
                 emp.Salary = employee.Salary;
                 db.SaveChanges();
                 return Request.CreateResponse(HttpStatusCode.OK, emp);
             }
         }
     }
     catch (Exception ex)
     {
         return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
     }
  }

After, modifying the method , again issue a put request via fiddler, you will Notice the web API is returning 200 Ok status code in the respone header. Also, when we try to update an employee whose id does not exist, we get status code 404 Not Found instead of 500 Internal Server Error.

Firing Put Request
Response Header for Put Request

Implementing Delete Method


  public void Delete(int id)
    {
     using (TestDbContext db = new TestDbContext())
     {
         Employee empToDelete = db.Employees.FirstOrDefault(e => e.Id == id);
         db.Employees.Remove(empToDelete);
         db.SaveChanges();
     }
   }

There are 2 problems with the above code
  1. When the deletion is successful since the method return type is void we get status code 204 No Content. We should be returning status code 200 OK.
  2. If the ID of the employee that we want to delete does not exist, it leads to a null reference exception, and as a result, the Web API returns status code 500 internal server error. But logically we should be returning the Status Code 404 that signifies an item not found.

To fix all the above problems, modify the code in Delete() method as shown below.


  public HttpResponseMessage Delete(int id)
   {
     try
     {
         using (TestDbContext db = new TestDbContext())
         {
             Employee emp = db.Employees.FirstOrDefault(e => e.Id == id);
             if (emp == null)
             {
                 return Request.CreateErrorResponse(HttpStatusCode.NotFound,
                     "Employee with Id = " + id.ToString() + " not found to delete");
             }
             else
             {
                 db.Employees.Remove(emp);
                 db.SaveChanges();
                 return Request.CreateResponse(HttpStatusCode.OK);
             }
         }
     }
     catch (Exception ex)
     {
         return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
     }
  }

At this point , we have successfully implemented Get, Post, Put and Delete Methods, so our web API is ready. Go, have some fun , listen to music and come after 10 minutes.

Now Let's create a MVC application, with all CRUD Methods

step 1) Go to File-->New--> project

step 2)Go to installed template-->visual c#-->Asp.Net Web Application.Here set Name and location for your application.

step 3)Select Empty Template and check MVC checkbox if you want an empty MVC template or Directly select MVC template if you need some code examples.

Below are the figures for above steps.

Create New MVC application Step-1
Step 1
Create New MVC application Step-2
Step 2
Create New MVC application Step-3
Step 3

In the right side you can see MVC directory structure with Model,View and MVC folder.This is called the solution explorer.As shown Below.

MVC directory Structure
MVC directory structure

Note:-If you are unable to see it then go to View-->Solution Explorer.

Now ,suppose we have to create a web application to show the details of Employess of any organization.

From here we will use Web API to retrieve or to Insert, Update or Delete Employee's data in our MVC Controller

step 1)create a controller and name it Employee controller.

note:-Each controller must suffix with Controller name ,so just change the prefix and keep the word controller as it is.

[Controller folder-->Right Click-->New-->controller]

Create New Controller in MVC
Create Employee Controller
Create New Controller in MVC step2
Create Employee Controller

Step 2)Go to Model folder and Create a class name it as Employee with some property.

Employee Model class
Create new Model in MVC

    public class Employee
     {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Salary { get; set; }
    }

Now it's time to consume Web API methods in Controller using:-
  1. HttpClient or
  2. RestClient

In order to use HttpClient in MVC application , we first need to add reference of System.Net.Http

Right click on References and Click on Add Reference and then select Framework tab and then check the System.Net.Http checkbox and click on ok.

Add reference of System.Net.Http
Add Reference
System.Net.Http Reference
Add reference of System.Net.Http

In order to parse the Json Response into .Net Object we need to add reference of Microsoft.AspNet.WebApi.Client.
The package is responsible for content-negtiation and formatting of data, it supports JSON, XML, and form URL encoded data formatting.


   Install-Package Microsoft.AspNet.WebApi.Client

Http Client will send request to web api based on the resource's URl, but the BaseUrl will be common whether it be a get, put, post or delete request , the baseurl is nothing but the hostname or domain name. So ,better is to save the BaseUrl in the configuration file of Application and read it anywhere in the application.

Right click on your Web API project and Go to properties and Copy the project URL as shown in below figure.

Web API Properties
Web API Properties
Base URL
BaseUrl(Project URL)

Now, open the configuration file of your MVC Application and save BaseUrl as key and value pair under AppSettings section.

Base URL Appsettings
AppSettings baseURL

match your configuration file with the codes shown below


   <configuration>
    <appsettings>
        <add key="webpages:Version" value="3.0.0.0" />
        <add key="webpages:Enabled" value="false" />
        <add key="ClientValidationEnabled" value="true" />
        <add key="UnobtrusiveJavaScriptEnabled" value="true" />
        <add key="Baseurl" value="http://localhost:3650/" />
     </appsettings>
     <system.web>
        <compilation debug="true" targetframework="4.5" />
        <httpruntime targetframework="4.5" />
    </system.web>
  </configuration>

Consume Web API Get Method in Asp.Net MVC using HttpClient


      public class EmployeeController : Controller
      {
        //
        // GET: /Employee/

        private readonly HttpClient client;
        private readonly string BaseUrl;
       
        public EmployeeController()
        {
            client = new HttpClient();
            BaseUrl = ConfigurationManager.AppSettings["url"];
            client.BaseAddress = new Uri(BaseUrl);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        }
        public ActionResult Index()
        {

            return View();
        }
       
     }

       public ActionResult GetAllEmployee()
        {
            List<Employee> emps = new List<Employee>();
            HttpResponseMessage getEmployee = client.GetAsync("api/Employee").Result;
            if (getEmployee.IsSuccessStatusCode)
            {
                emps = getEmployee.Content.ReadAsAsync<List<Employee>>().Result.ToList();

                return Json(emps,JsonRequestBehavior.AllowGet) ;
            }
            else
            {
                return null;
            }
        }


     public ActionResult GetEmployeeById(int id)
        {
            try
            {
                Employee emp=new Employee();
                if (ModelState.IsValid)
                {
                    HttpResponseMessage response = client.GetAsync("api/Employee/" + id).Result;

                    if (response.IsSuccessStatusCode)
                    {
                        emp=response.Content.ReadAsAsync<Employee>().Result;
                    }

                }
                return Json(emp, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return Json(ex.Message);
            }
        }

Let's understand the above code.
  • To send a get request I have used the HttpClient's extension method GetAsync, which takes the resource URL parameter and returns a task of HttpResponseMessage.
  • In order to get the result from a Task we use dot Result.
  • I am storing the result on a variable called employee.
  • Then I am checking, whether we are getting a successful response or not.
  • Using IsSuccessStatusCode property of HttpResponseMessage which returns a bool if request is successfull and status code is 200 Ok.
  • Then I am reading the result into a List of Employees using the ReadAsAsync extension method of HttpContent of HttpResponseMessage and storing the List into a variable named emps.
  • Lastly i am sending the json result with List.
  • The same has been used in the GetEmployeeById method, where we are reading the result into an employee object instead of a list.

Consume Web API Post Method in Asp.Net MVC using HttpClient


   [HttpPost]
        public int AddEmployees(Employee employee)
        {
            try
            {
                if (ModelState.IsValid)
                {

                    var getEmployee = client.PostAsJsonAsync("api/Employee", employee).Result;
                    if (getEmployee.IsSuccessStatusCode)
                    {
                        return 1;
                    }

                }
                return 0;
            }
            catch (Exception ex)
            {
                return 0;
            }
        }

Let's understand the above code.
  • To send a Post request I have used the HttpClient's extension method PostAsJsonAsync , which takes the resource url and Object to be passed as parameter and returns a task of HttpResponseMessage.
  • Inorder to get the result from a Task we use dot Result.
  • I am storing the result on a variable called getEmployee.
  • Then i am checking ,whether we are getting successfull response or not using IsSuccessStatusCode property of HttpResponseMessage which returns a bool if request is successfull and status code is 200 Ok.
  • Lastly I am returning 1 if response was successful or 0 if request failed.

Consume Web API Put Method in Asp.Net MVC using HttpClient


   [HttpPost]
        public ActionResult UpdateEmployee(Employee emp)
        {
            
            try
            {
                if (ModelState.IsValid)
                {
                    HttpResponseMessage response = client.PutAsJsonAsync("api/Employee /" + emp.Id, emp).Result;

                    if (response.IsSuccessStatusCode)
                    {
                    }

                }
                return RedirectToAction("GetAllEmployee", "Employee");
            }
            catch (Exception ex)
            {
                return Json(ex.Message);
            }
        }

Let's understand the above code.
  • To send a put request i have used the HttpClient's extension method PutAsJsonAsync , which takes the resource url and Object to be passed as parameter and returns a task of HttpResponseMessage.
  • Inorder to get the result from a Task we use dot Result.
  • I am storing the result on a variable called response.
  • Then i am checking ,whether we are getting successfull response or not using IsSuccessStatusCode property of HttpResponseMessage which returns a bool if request is successfull and status code is 200 Ok.
  • Lastly i am returning 1 if response was successfull or 0 if request failed.

Consume Web API Delete Method in Asp.Net MVC using HttpClient


    [HttpPost]
        public int DeleteEmployee(int Id)
        {
            try
            {           
                HttpResponseMessage response = client.DeleteAsync("api/Employee/"+Id).Result;
            
                if (response.IsSuccessStatusCode)
                {
                         return 1;
                }

                return 0;
            }
            catch (Exception ex)
            {
                return 0;
            }

        }

Let's understand the above code.
  • To send a put request i have used the HttpClient's extension method DeleteAsync , which takes the resource url as parameter and returns a task of HttpResponseMessage.
  • Inorder to get the result from a Task we use dot Result.
  • I am storing the result on a variable called response.
  • Then I am checking ,whether we are getting successfull response or not using IsSuccessStatusCode property of HttpResponseMessage which returns a bool if request is successfull and status code is 200 Ok.
  • Lastly I am returning 1 if response was successfull or 0 if request failed.

following is the code for view , I have used jquery datatable to look view good and professional , for edit I have used bootstrap modal popup.


  @{
    ViewBag.Title = "Index";
    Layout = null;
    }

   <h2>Index</h2>
   <!-- Latest compiled and minified CSS -->
   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.css">
   <link href="https://cdn.datatables.net/1.10.22/css/dataTables.bootstrap4.min.css" rel="stylesheet" />
   <!-- jQuery library -->
   <!-- Latest compiled JavaScript -->
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
   <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
   <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
  
   <div class="card">
    <div class="card-header">
        <div class="row">
        	<div class="col-md-6 offset-md-6"><button class="btn btn-primary float-right" id="btnAdd">+Add</button></div>
        	
        </div>
    </div>
    <table class="table table-striped table-bordered" style="width:100%" id="tblEmployee">
        <thead class="thead-dark">
            <tr>
                <th>#</th>
                <th>Name</th>
                <th>Salary</th>
                <th>Edit</th>
                <th>Delete</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
  </div>

  <div class="modal" id="myModal" tabindex="-1" role="dialog" aria-labelledby="editModel" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalCenterTitle">Edit Employee</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">×</span>
                </button>
            </div>
            <div class="modal-body">
                <form>
                    <div class="row">
                        <div class="col">
                            <input type="text" id="txtName" class="form-control" placeholder="Name">
                        </div>
                        <div class="col">
                            <input type="number" id="txtSalary" class="form-control" placeholder="Salary">
                        </div>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="button" id="btnUpdate" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
   </div>

   <div class="modal" id="modalAdd" tabindex="-1" role="dialog" aria-labelledby="editModel" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalCenterTitle">Edit Employee</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">×</span>
                </button>
            </div>
            <div class="modal-body">
                <form>
                    <div class="row">
                        <div class="col">
                            <input type="text" id="txtName1" class="form-control" placeholder="Name">
                        </div>
                        <div class="col">
                            <input type="number" id="txtSalary1" class="form-control" placeholder="Salary">
                        </div>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary" id="btnInsert">Save changes</button>
            </div>
        </div>
    </div>
   </div>
   <script type="text/javascript">
    $(document).ready(function () {
      
        $("#tblEmployee").dataTable({

            ajax: {
                type: "get",
                url: "/Employee/GetAllEmployee",
                dataType: "json",
                dataSrc: ""

            },
            columns: [{ 'data': 'Id' },
                      { 'data': 'Name' },
                      { 'data': 'Salary' },
                      {
                          'data': 'Id', render: function (data, type, row) {
                              return '<button class="btn btn-info btn-sm btnEdit" data-Id=' + row.Id + '>' + 'Edit' + '</button>';

                          }
                      },
                      {
                          'data': 'Id', render: function (data, type, row) {
                              return '<button class="btn btn-info btn-sm btnDelete" data-Id=' + row.Id + '>' + 'Delete' + '</button>';

                          }
                      }
            ]


        });
    });

    $("#tblEmployee").on('click','.btnEdit',function(){      
        debugger;
        var Id = $(this).attr("data-Id");

        $.ajax({
            type: "POST",
            url: "/Employee/GetEmployeeById/"+Id,
         
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) {
                debugger;
                var Name = data.Name;
                var Salary = data.Salary;
                $("#txtName").val(Name);
                $("#txtSalary").val(Salary);
                $("#myModal").modal('show');
              
            },
            failure: function (response) {
                alert(response.d);
            },
            error: function (response) {
                alert(response.d);
            }
        });       
    });       
    
    $("#tblEmployee").on('click', '.btnDelete', function ()
    {
        var Id = $(this).attr("data-Id");

        $.ajax({
            type: "POST",
            url: "/Employee/DeleteEmployee/" + Id,

            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) {
                debugger;
                $('#tblEmployee').DataTable().ajax.reload();

            },
            failure: function (response) {
                alert(response.d);
            },
            error: function (response) {
                alert(response.d);
            }
        });
    });

    $("#btnAdd").click(function () {

        $("#modalAdd").modal("show");
    });

    $("#btnInsert").click(function () {
        debugger;   
        var employee = {
            "Name": $("#txtName1").val(),
            "Salary": $("#txtSalary1").val(),
        }     
        $.ajax({
            type: "POST",
            url: '/employee/AddEmployees',
            data: JSON.stringify(employee),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            cache: false,
            success: function (data) {
                $('#tblEmployee').DataTable().ajax.reload();
                $("#modalAdd").modal("hide");
            },
        });

    });
  
    $("#btnUpdate").click(function () {
        debugger;  
        var emp = {
          
            Name: $("#txtName").val(),
            Salary: $("#txtSalary").val(),
        }
        $.ajax({
            type: "POST",
            url: '/employee/UpdateEmployee',
            data:JSON.stringify(emp),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            cache: false,
            success: function (data) {
                $('#tblEmployee').DataTable().ajax.reload();
                $("#myModal").modal('hide');
            },
        });
    });
  </script>

Here, I have used Ajax method to load data into datatable by sending request to GetAllEmployee method.
For edit , I have send a post request request to GetEmployeeById method and onSuccess function loaded a form with returned data which opens in a modal popup.
For update, I have send a Post Request to UpdateEmployee method and then on Success function I refreshed the dataTable.
For Delete, I have send a Post Request to DeleteEmployee method and then on Success function I refreshed the dataTable.
For Adding Employee I have send a Post Request to AddEmployee method and on Success function I refreshed the dataTable.
To Run the application , Right click on solution and go to properties and check multiple startupProjects checkbox and start both web API and MVC application and then run your application.

solution properties
Solution Properties
start multi project
start multiple project

Also, modify your route.config of MVC application to run the employee controller index action method as default.


public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Employee", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

this is how our application looks like.

start multi project
start multiple project

In the next article we will learn how to consume web api methods directly from view