Carl Rippon

Building SPAs

Carl Rippon
BlogBooks / CoursesAbout
This site uses cookies. Click here to find out more

Calling an ASP.NET Web API from jQuery

January 08, 2017
dotnetjquery

I’ve been playing with ASP.NET Core Web API recently … here’s a quick post on calling one of these APIs using jQuery Ajax …

Creating the API

The API is going to allow clients to:

  • get a list of people
  • get a single person
  • create a new person

Here’s the very simple person model:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

For simplicity, I’m going to use a hardcoded list of people and not going to persist the people in a database. Here’s the API controller constructor and the hardcoded list:

private List<Person> People;

public PersonController()
{
    People = new List()
    {
        new Person() {Id=1, Name = "Fred Blogs", Email="fred.blogs@someemail.com" },
        new Person() {Id=2, Name = "James Smith", Email="james.smith@someemail.com" },
        new Person() {Id=3, Name = "Jerry Jones", Email="jerry.jones@someemail.com" }
    };
}

The action method in PersonController to get the list of all the people is very simple:

// GET: api/person
[HttpGet]
public IActionResult Get()
{
    return new ObjectResult(People);
}

The action method in PersonController to get a single person is below. The person id will be passed in from the URL path. We return the “Not Found” HTTP status code if the id isn’t in our hardcoded list and the JSON represenation of the found person if it does exists.

// GET api/person/id
[HttpGet("{id}",Name ="GetPerson")]
public IActionResult Get(int id)
{
    Person person = (from p in People where p.Id == id select p).FirstOrDefault();
    if (person == null)
    {
        return NotFound();
    }
    else
    {
        return new ObjectResult(person);
    }
}

The action method in PersonController to create a person is below. The person object is passed in from the HTTP body that has been posted. If the body is missing we return a “Bad Request” HTTP status code. If we do have a person object from the HTTP body then the person id is generated, the person is added to the hardcoded list and we return a “Created” HTTP status code with the person in the response body containing the generated person id.

As well as dealing with returning the HTTP status code and the response body, the call to CreatedAtRoute(), also sets the Location HTTP header to the URL that the client could use to request the person just created. This is the reason for the Get action method having the GetPerson name parameter in the attribute and being referenced as the first parameter in CreatedAtRoute().

// POST api/person
[HttpPost]
public IActionResult Post([FromBody]Person person)
{
    if (person == null)
    {
        return BadRequest();
    }
    int nextId = (from p in People select p.Id).Max() + 1;
    person.Id = nextId;
    People.Add(person);
    return CreatedAtRoute("GetPerson", new { id = nextId }, person);
}

Creating the frontend page

Below is the HTML markup (referencing bootstrap CSS classes) that allows the user get a list of people:

<div class="container">
  <div class="row">
    <div class="col-sm-6">
      <h2>Get all people</h2>
      <div>
        <button class="btn btn-default" id="getPeople">Get People</button>
      </div>
      <div>
        <input type="text" class="form-control" id="getPeopleResult" />
      </div>
    </div>
  </div>
</div>

Below is JavaScript for the getPeople button click handler. We use $.ajax() to call our person API. It is important to set contentType to application/json or our API won’t be reached. We put the names of the people returned in a pipe delimited list into the getPeopleResult textbox if the API call is successful.

<script>
$('#getPeople').click(function (e) {
    $("#getPeopleResult").val("");
    $.ajax({
        contentType: 'application/json',
        type: "GET",
        url: "api/person",
        success: function (data, textStatus, jqXHR) {
            data.forEach(function (person) {
                $("#getPeopleResult").val($("#getPeopleResult").val() + person.name + "|");
            });
        },
        error: function (jqXHR, textStatus, errorThrown) {
            $("#getPeopleResult").val(jqXHR.statusText);
        }
    });
});
</script>

Below is the HTML markup (referencing bootstrap CSS classes) that allows the user to get a single person:

<div class="container">
  <div class="row">
    <div class="col-sm-6">
      <h2>Get a Person</h2>
      <div class="form-group">
        <label for="id">Id</label>
        <input type="text" class="form-control" id="id" />
      </div>
      <div>
        <button class="btn btn-default" id="getPerson">Get</button>
      </div>
      <div>
        <input type="text" class="form-control" id="getPersonResult" />
      </div>
    </div>
  </div>
</div>

Below is JavaScript for the getPerson button click handler. The code is very simular to the getPeople button click handler except it calls the API to get a single person and outputs the single person’s name in the getPersonResult textbox.

$("#getPerson").click(function(e) {
  $("#getPersonResult").val("");
  $.ajax({
    contentType: "application/json",
    type: "GET",
    url: "api/person/" + $("#id").val(),
    success: function(data, textStatus, jqXHR) {
      $("#getPersonResult").val(data.name);
    },
    error: function(jqXHR, textStatus, errorThrown) {
      $("#getPersonResult").val(jqXHR.statusText);
    }
  });
});

Below is the HTML markup that allows the user to create a person:

<div class="container">
  <div class="row">
    <div class="col-sm-6">
      <h2>Create a new Person</h2>
      <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name" />
      </div>
      <div class="form-group">
        <label for="emailAddress">Email</label>
        <input type="email" class="form-control" id="emailAddress" />
      </div>
      <div>
        <button class="btn btn-default" id="create">Create</button>
      </div>
      <div>
        <input type="text" class="form-control" id="postResult" />
      </div>
    </div>
  </div>
</div>

Below is JavaScript for the create button click handler. Again we use $.ajax() to call our person API but this time we POST to it. We create an object literal containing the name and email of the person and use JSON.stringify() so this can be passed into the data option in $.ajax(). We set whether the operation has been successful in the postResult textbox along with the generated person id. It is worth noting that the data in the success callback is the original data and not the data in the response. The response body can be obtained from jqXHR.responseText.

$("#create").click(function(e) {
  $.ajax({
    contentType: "application/json",
    type: "POST",
    url: "api/person",
    data: JSON.stringify({
      name: document.getElementById("name").value,
      email: document.getElementById("emailAddress").value
    }),
    success: function(data, textStatus, jqXHR) {
      $("#postResult").val("Person created ok. Id=" + jqXHR.responseText);
    },
    error: function(jqXHR, textStatus, errorThrown) {
      $("#postResult").val(jqXHR.statusText);
    }
  });
});

If you to learn about using React with ASP.NET Core you might find my book useful:

ASP.NET Core 5 and React

ASP.NET Core 5 and React
Find out more

Want more content like this?

Subscribe to receive notifications on new blog posts and courses

Required
© Carl Rippon
Privacy Policy