Tutorial: Call an ASP.NET Core web API with jQuery

By Rick Anderson

This tutorial shows how to call an ASP.NET Core web API with jQuery

For ASP.NET Core 2.2, see the 2.2 version of Call the Web API with jQuery.

Prerequisites

Call the API with jQuery

In this section, an HTML page is added that uses jQuery to call the web api. jQuery initiates the request and updates the page with the details from the API's response.

Configure the app to serve static files and enable default file mapping by updating Startup.cs with the following highlighted code:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseDefaultFiles();
    app.UseStaticFiles();

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Create a wwwroot folder in the project directory.

Add an HTML file named index.html to the wwwroot directory. Replace its contents with the following markup:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>To-do CRUD</title>
    <style>
        input[type='submit'], button, [aria-label] {
            cursor: pointer;
        }

        #spoiler {
            display: none;
        }

        table {
            font-family: Arial, sans-serif;
            border: 1px solid;
            border-collapse: collapse;
        }

        th {
            background-color: #0066CC;
            color: white;
        }

        td {
            border: 1px solid;
            padding: 5px;
        }
    </style>
</head>
<body>
    <h1>To-do CRUD</h1>
    <h3>Add</h3>
    <form action="javascript:void(0);" method="POST" onsubmit="addItem()">
        <input type="text" id="add-name" placeholder="New to-do">
        <input type="submit" value="Add">
    </form>

    <div id="spoiler">
        <h3>Edit</h3>
        <form class="my-form">
            <input type="hidden" id="edit-id">
            <input type="checkbox" id="edit-isComplete">
            <input type="text" id="edit-name">
            <input type="submit" value="Save">
            <a onclick="closeInput()" aria-label="Close">&#10006;</a>
        </form>
    </div>

    <p id="counter"></p>

    <table>
        <tr>
            <th>Is Complete</th>
            <th>Name</th>
            <th></th>
            <th></th>
        </tr>
        <tbody id="todos"></tbody>
    </table>

    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.js" 
            integrity="sha384-mlceH9HlqLp7GMKHrj5Ara1+LvdTZVMx4S1U43/NxCvAkzIo8WJ0FE7duLel3wVo" 
            crossorigin="anonymous"></script>
    <script src="site.js"></script>
</body>
</html>

Add a JavaScript file named site.js to the wwwroot directory. Replace its contents with the following code:

const uri = 'api/TodoItems';
let todos = null;
function getCount(data) {
  const el = $('#counter');
  let name = 'to-do';
  if (data) {
    if (data > 1) {
      name = 'to-dos';
    }
    el.text(data + ' ' + name);
  } else {
    el.text('No ' + name);
  }
}

$(document).ready(function() {
  getData();
});

function getData() {
  $.ajax({
    type: 'GET',
    url: uri,
    cache: false,
    success: function(data) {
      const tBody = $('#todos');

      $(tBody).empty();

      getCount(data.length);

      $.each(data, function(key, item) {
        const tr = $('<tr></tr>')
          .append(
            $('<td></td>').append(
              $('<input/>', {
                type: 'checkbox',
                disabled: true,
                checked: item.isComplete
              })
            )
          )
          .append($('<td></td>').text(item.name))
          .append(
            $('<td></td>').append(
              $('<button>Edit</button>').on('click', function() {
                editItem(item.id);
              })
            )
          )
          .append(
            $('<td></td>').append(
              $('<button>Delete</button>').on('click', function() {
                deleteItem(item.id);
              })
            )
          );

        tr.appendTo(tBody);
      });

      todos = data;
    }
  });
}

function addItem() {
  const item = {
    name: $('#add-name').val(),
    isComplete: false
  };

  $.ajax({
    type: 'POST',
    accepts: 'application/json',
    url: uri,
    contentType: 'application/json',
    data: JSON.stringify(item),
    error: function(jqXHR, textStatus, errorThrown) {
      alert('Something went wrong!');
    },
    success: function(result) {
      getData();
      $('#add-name').val('');
    }
  });
}

function deleteItem(id) {
  $.ajax({
    url: uri + '/' + id,
    type: 'DELETE',
    success: function(result) {
      getData();
    }
  });
}

function editItem(id) {
  $.each(todos, function(key, item) {
    if (item.id === id) {
      $('#edit-name').val(item.name);
      $('#edit-id').val(item.id);
      $('#edit-isComplete')[0].checked = item.isComplete;
    }
  });
  $('#spoiler').css({ display: 'block' });
}

$('.my-form').on('submit', function() {
  const item = {
    name: $('#edit-name').val(),
    isComplete: $('#edit-isComplete').is(':checked'),
    id: parseInt($('#edit-id').val(), 10)
  };

  $.ajax({
    url: uri + '/' + $('#edit-id').val(),
    type: 'PUT',
    accepts: 'application/json',
    contentType: 'application/json',
    data: JSON.stringify(item),
    success: function(result) {
      getData();
    }
  });

  closeInput();
  return false;
});

function closeInput() {
  $('#spoiler').css({ display: 'none' });
}

A change to the ASP.NET Core project's launch settings may be required to test the HTML page locally:

  • Open Properties\launchSettings.json.
  • Remove the launchUrl property to force the app to open at index.html—the project's default file.

There are several ways to get jQuery. In the preceding snippet, the library is loaded from a CDN.

This sample calls all of the CRUD methods of the API. Following are explanations of the calls to the API.

Get a list of to-do items

The jQuery ajax function sends a GET request to the API, which returns JSON representing an array of to-do items. The success callback function is invoked if the request succeeds. In the callback, the DOM is updated with the to-do information.

$(document).ready(function() {
  getData();
});

function getData() {
  $.ajax({
    type: 'GET',
    url: uri,
    cache: false,
    success: function(data) {
      const tBody = $('#todos');

      $(tBody).empty();

      getCount(data.length);

      $.each(data, function(key, item) {
        const tr = $('<tr></tr>')
          .append(
            $('<td></td>').append(
              $('<input/>', {
                type: 'checkbox',
                disabled: true,
                checked: item.isComplete
              })
            )
          )
          .append($('<td></td>').text(item.name))
          .append(
            $('<td></td>').append(
              $('<button>Edit</button>').on('click', function() {
                editItem(item.id);
              })
            )
          )
          .append(
            $('<td></td>').append(
              $('<button>Delete</button>').on('click', function() {
                deleteItem(item.id);
              })
            )
          );

        tr.appendTo(tBody);
      });

      todos = data;
    }
  });
}

Add a to-do item

The ajax function sends a POST request with the to-do item in the request body. The accepts and contentType options are set to application/json to specify the media type being received and sent. The to-do item is converted to JSON by using JSON.stringify. When the API returns a successful status code, the getData function is invoked to update the HTML table.

function addItem() {
  const item = {
    name: $('#add-name').val(),
    isComplete: false
  };

  $.ajax({
    type: 'POST',
    accepts: 'application/json',
    url: uri,
    contentType: 'application/json',
    data: JSON.stringify(item),
    error: function(jqXHR, textStatus, errorThrown) {
      alert('Something went wrong!');
    },
    success: function(result) {
      getData();
      $('#add-name').val('');
    }
  });
}

Update a to-do item

Updating a to-do item is similar to adding one. The url changes to add the unique identifier of the item, and the type is PUT.

$.ajax({
  url: uri + '/' + $('#edit-id').val(),
  type: 'PUT',
  accepts: 'application/json',
  contentType: 'application/json',
  data: JSON.stringify(item),
  success: function(result) {
    getData();
  }
});

Delete a to-do item

Deleting a to-do item is accomplished by setting the type on the AJAX call to DELETE and specifying the item's unique identifier in the URL.

$.ajax({
  url: uri + '/' + id,
  type: 'DELETE',
  success: function(result) {
    getData();
  }
});

Advance to the next tutorial to learn how to generate API help pages: