In this post, we will discuss, how to call WebAPI in ASP.NET core using HttpClient. This tutorial introduces the use of HttpClient libraries to make ASP.NET Web API calls. A Windows application, console application, or even a Windows 8 application can use the HttpClient library to call your WebAPI.
The last post in this series, “Using ASP.NET WebAPI with WebForms”, demonstrated how to create a WebAPI to be used with WPF.
Let’s create a WPF application project:
Select New -> Project from Visual Studio 2019. From the left-hand navigation, select Visual C# -> Windows and then WPF Application from the project type drop-down list. WebAPIClient is the name of the project.
Let’s install WebAPI client libraries:
In our project, we’ll use NuGet Package Manager to install the HttpClient libraries, which makes it very easy for us to do so.
To manage NuGet packages for a solution, use Library Package Manager under the Tools menu
To install the Microsoft HTTP Client Libraries, select the Microsoft HTTP Client Libraries in the Manage NuGet Packages dialog box, which opens:
When you select Install, you are asked to choose the project where the application should be installed. The installation will be complete once you click Ok.
From Nuget Package Manager, install the package “JSON.Net”.
Create the User Interface
It is next on our list of things to add to our application, including adding a DataGrid to display user information and adding a textbox and button to take input from the user.
A sample MainWindows.xaml code can be found here:
XML
Shrink ▲
<Window x:Class="WebAPIClient.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="500" Width="525">
<Grid Margin="0,0,-8,-122">
<DataGrid Name="usergrid"
HorizontalAlignment="Left" Margin="28,23,0,0"
AutoGenerateColumns="True"
VerticalAlignment="Top" Height="185" Width="451"/>
<Label Content="First Name" HorizontalAlignment="
Left" Margin="28,259,0,0" VerticalAlignment="Top"
RenderTransformOrigin="-0.085,-0.243"/>
<TextBox x:Name="txtFirst" HorizontalAlignment="Left"
Height="23" Margin="138,259,0,0" TextWrapping="Wrap"
VerticalAlignment="Top" Width="120"/>
<Label Content="Last Name" HorizontalAlignment="Left"
Margin="290,259,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="txtLas" HorizontalAlignment="Left"
Height="23" Margin="372,259,0,0" TextWrapping="Wrap"
VerticalAlignment="Top" Width="120"/>
<Label Content="Company" HorizontalAlignment="Left"
Margin="28,311,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.085,-0.243"/>
<Label Content="Email" HorizontalAlignment="Left"
Margin="290,311,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="txtEmail" HorizontalAlignment="Left"
Height="23" Margin="372,311,0,0" TextWrapping="Wrap"
VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="txtCompany" HorizontalAlignment="Left"
Height="23" Margin="138,311,0,0" TextWrapping="Wrap"
VerticalAlignment="Top" Width="120"/>
<Label Content="Phone" HorizontalAlignment="Left"
Margin="28,360,0,0" VerticalAlignment="Top"
RenderTransformOrigin="-0.085,-0.243"/>
<TextBox x:Name="txtPhone" HorizontalAlignment="Left"
Height="23" Margin="138,360,0,0" TextWrapping="Wrap"
VerticalAlignment="Top" Width="120"/>
<Button Content="Add User" HorizontalAlignment="Left"
Margin="290,366,0,0" VerticalAlignment="Top"
Width="75" Click="Button_Click_1"/>
<TextBox HorizontalAlignment="Left" Height="23"
Margin="53,404,0,0" TextWrapping="Wrap" x:Name="txtSearch"
Text="" VerticalAlignment="Top" Width="120"/>
<Button Content="Search" HorizontalAlignment="Left"
Margin="204,407,0,0" VerticalAlignment="Top"
Width="75" x:Name="btnSearch"/>
<Button Content="Show All" HorizontalAlignment="Left"
Margin="290,407,0,0" VerticalAlignment="Top"
Width="75" x:Name="btnShowAll"/>
<TextBox HorizontalAlignment="Left" Height="23"
Margin="53,445,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="120" x:Name="txtDelete"/>
<Button Content="Delete" HorizontalAlignment="Left"
Margin="204,448,0,0" VerticalAlignment="Top"
Width="75" x:Name="btnDelete"/>
</Grid>
</Window>
As an example of our UI, here is what it will look like:
Create Model Class
In order to read and write data to the WebAPI, we will create a Model class called “Users.cs”.
C#
public class Users
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
public string Email { get; set; }
public string PhoneNo { get; set; }
}
Creating HTTP Client
This project includes a reference to the System.Net.Http.Formatting assembly and a function that calls the WebAPI using the Client library and gets the user list.
C#
Shrink ▲
private void GetData()
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:56851/");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("api/User").Result;
if (response.IsSuccessStatusCode)
{
var users = response.Content.ReadAsAsync&
lt;IEnumerable<Users>>().Result;
usergrid.ItemsSource = users;
}
else
{
MessageBox.Show("Error Code" +
response.StatusCode + " : Message - " + response.ReasonPhrase);
}
}
The method begins by creating a new HttpClient instance and setting its base address to “http://localhost:56851?”. Our API should be running at this address. In the previous tutorial, you created an API and you needed to set the port number accordingly.
In this case, we are instructing the server to send a Json response by setting the Accept header property to “application/json”.
A HTTP Get request will be displayed to “api/User” after calling the “GetAsync” method. The server will not wait for the request to return because it is asynchronous. The “Result” property of the Task class can be used to retrieve the response from the returned Task object. Due to the Result property being used, we are blocking the call while we wait for a response. For real projects, it is better to use Non Blocking calls to ensure that your UI is always active. To keep this example simple, we will continue to use it, despite the fact that it is not a good practice when working with Windows applications.
Once the response is received, we check if it indicates that the request has been successful. Our data will be returned in JSON format if the request is successful.
As a result, we are able to deserialize our Users type by using the “ReadAsAsync()” method. The Result property makes this method a blocking call, even though it is also asynchronous. Afterwards, the result is binded to the DataGrid and displayed.
In order to make this work, please make sure you have downloaded and run the Web API from my previous post.
The following screen appears when you launch the application:
Add a User (POST)
Add a User is performed by the following code when the Add User button is clicked:
C#
Shrink ▲
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:56851/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var user = new Users();
user.FirstName = txtFirst.Text;
user.Company = txtCompany.Text;
user.LastName = txtLas.Text;
user.Email = txtEmail.Text;
user.PhoneNo = txtPhone.Text;
user.Email = txtEmail.Text;
var response = client.PostAsJsonAsync("api/User", user).Result;
if (response.IsSuccessStatusCode)
{
MessageBox.Show("User Added");
txtFirst.Text = "";
txtLas.Text = "";
txtPhone.Text = "";
txtEmail.Text = "";
txtCompany.Text = "";
GetData();
}
else
{
MessageBox.Show("Error Code" +
response.StatusCode + " : Message - " + response.ReasonPhrase);
}
The base address is again passed to the client object, as well as the headers. After collecting information from the textbox, we create a Users object.
We send the user object created earlier to the library’s “PostAsJsonAsync” method. In this case, the DataGrid is refreshed to reflect the successful addition of the user.
Searching for a User
On clicking the search button, the following code is called
C#
Shrink ▲
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:56851/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var id = txtSearch.Text.Trim();
var url = "api/User/" + id;
HttpResponseMessage response = client.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
var users = response.Content.ReadAsAsync<Users>().Result;
MessageBox.Show("User Found : " +
users.FirstName + " " + users.LastName);
}
else
{
MessageBox.Show("Error Code" +
response.StatusCode + " : Message - " + response.ReasonPhrase);
}
As with our earlier Get Request, this code is similar. Our API request now includes the user’s “id” while constructing the URL.
As a single user will be returned when we read the response, we use a single User object. Our WebAPI throws an HTTP Response Exception if the user cannot be found based on the id.
Deleting a User
As a result of clicking the Delete Button, we are calling the following code:
C#
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:56851/");
var id = txtDelete.Text.Trim();
var url = "api/User/" + id;
HttpResponseMessage response = client.DeleteAsync(url).Result;
if (response.IsSuccessStatusCode)
{
MessageBox.Show("User Deleted");
GetData();
}
else
{
MessageBox.Show("Error Code" +
response.StatusCode + " : Message - " + response.ReasonPhrase);
}
The code is the same as that of the Search User. In order to delete a user, we pass the Id of the user to create the URL.
This will delete the User of the specified id using the “DeleteAsync” method of the library. An exception will be thrown if no user can be found.
Thank you for taking the time to read the article. I would appreciate it if you could let me know if you encounter any errors.
To run the WPF application, please run the WebAPI demo project first.