In this article we are going to learn how we can call Web API using HttpClient. Normally we call a Web API either from a jQuery Ajax or from AngularJS, right? Recently, I came across a need of calling our Web API from the server side itself. Here I am going to use two Visual Studio applications. One is our normal Web API application in which I have a Web API controller and actions, another one is a console application where I consume my Web API. Sounds good? I am using Visual Studio 2015.
Now we will go and create our application. I hope you will like this.
You can always download the source code here.
Background
We all use Web API in our applications to implement Http services. Http services are much simpler than ever if we use Web API. But the fact is, the benefits of a Web API are not limited to that. Previously we used WCF services instead of Web API, where we were working with endpoints and all. Here, I am going to explain an important feature of a Web API that we can call Web API from our server itself instead of using an Ajax Call. That is pretty cool, right? Now we will create our application.
Firstly, we will create our Web API application.
Creating Web API application
Click File, New, then Project and then select MVC application. From the following pop up we will select the template as empty and select the core references and folders for MVC.
Figure: Empty Template With MVC And Web API Folders
Once you click OK, a project with MVC like folder structure with core references will be created for you.
Figure: Folder Structure And References For Empty MVC Project
Using the code
We will set up our database first so that we can create Entity Model for our application later.
Create a database
The following query can be used to create a database in your SQL Server.
- USE [master]
- GO
- /****** Object: Database [TrialsDB]
- CREATE DATABASE [TrialsDB]
- CONTAINMENT = NONE
- ON PRIMARY
- ( NAME = N'TrialsDB', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\TrialsDB.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
- LOG ON
- ( NAME = N'TrialsDB_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\TrialsDB_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
- GO
- ALTER DATABASE [TrialsDB] SET COMPATIBILITY_LEVEL = 110
- GO
- IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
- begin
- EXEC [TrialsDB].[dbo].[sp_fulltext_database] @action = 'enable'
- end
- GO
- ALTER DATABASE [TrialsDB] SET ANSI_NULL_DEFAULT OFF
- GO
- ALTER DATABASE [TrialsDB] SET ANSI_NULLS OFF
- GO
- ALTER DATABASE [TrialsDB] SET ANSI_PADDING OFF
- GO
- ALTER DATABASE [TrialsDB] SET ANSI_WARNINGS OFF
- GO
- ALTER DATABASE [TrialsDB] SET ARITHABORT OFF
- GO
- ALTER DATABASE [TrialsDB] SET AUTO_CLOSE OFF
- GO
- ALTER DATABASE [TrialsDB] SET AUTO_CREATE_STATISTICS ON
- GO
- ALTER DATABASE [TrialsDB] SET AUTO_SHRINK OFF
- GO
- ALTER DATABASE [TrialsDB] SET AUTO_UPDATE_STATISTICS ON
- GO
- ALTER DATABASE [TrialsDB] SET CURSOR_CLOSE_ON_COMMIT OFF
- GO
- ALTER DATABASE [TrialsDB] SET CURSOR_DEFAULT GLOBAL
- GO
- ALTER DATABASE [TrialsDB] SET CONCAT_NULL_YIELDS_NULL OFF
- GO
- ALTER DATABASE [TrialsDB] SET NUMERIC_ROUNDABORT OFF
- GO
- ALTER DATABASE [TrialsDB] SET QUOTED_IDENTIFIER OFF
- GO
- ALTER DATABASE [TrialsDB] SET RECURSIVE_TRIGGERS OFF
- GO
- ALTER DATABASE [TrialsDB] SET DISABLE_BROKER
- GO
- ALTER DATABASE [TrialsDB] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
- GO
- ALTER DATABASE [TrialsDB] SET DATE_CORRELATION_OPTIMIZATION OFF
- GO
- ALTER DATABASE [TrialsDB] SET TRUSTWORTHY OFF
- GO
- ALTER DATABASE [TrialsDB] SET ALLOW_SNAPSHOT_ISOLATION OFF
- GO
- ALTER DATABASE [TrialsDB] SET PARAMETERIZATION SIMPLE
- GO
- ALTER DATABASE [TrialsDB] SET READ_COMMITTED_SNAPSHOT OFF
- GO
- ALTER DATABASE [TrialsDB] SET HONOR_BROKER_PRIORITY OFF
- GO
- ALTER DATABASE [TrialsDB] SET RECOVERY FULL
- GO
- ALTER DATABASE [TrialsDB] SET MULTI_USER
- GO
- ALTER DATABASE [TrialsDB] SET PAGE_VERIFY CHECKSUM
- GO
- ALTER DATABASE [TrialsDB] SET DB_CHAINING OFF
- GO
- ALTER DATABASE [TrialsDB] SET FILESTREAM( NON_TRANSACTED_ACCESS = OFF )
- GO
- ALTER DATABASE [TrialsDB] SET TARGET_RECOVERY_TIME = 0 SECONDS
- GO
- ALTER DATABASE [TrialsDB] SET READ_WRITE
- GO
Now we will create the table we need. As of now I am going to create the tabletblTags
Create tables in database
Below is the query to create the tabletblTags.
- USE [TrialsDB]
- GO
- /****** Object: Table [dbo].[tblTags] Script Date: 23-Mar-16 5:01:22 PM ******/
- SET ANSI_NULLS ON
- GO
- SET QUOTED_IDENTIFIER ON
- GO
- CREATE TABLE [dbo].[tblTags](
- [tagId] [int] IDENTITY(1,1) NOT NULL,
- [tagName] [nvarchar](50) NOT NULL,
- [tagDescription] [nvarchar](max) NULL,
- CONSTRAINT [PK_tblTags] PRIMARY KEY CLUSTERED
- (
- [tagId] ASC
- )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
- ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
- GO
Can we insert some data to the tables now?
Insert data to table
You can use the below query to insert the data to the tabletblTags,
- USE[TrialsDB]
- GO
- INSERT INTO[dbo].[tblTags]
- ([tagName], [tagDescription])
- VALUES( < tagName, nvarchar(50), > , < tagDescription, nvarchar(max), > )
- GO
Next thing we are going to do is creating a ADO.NET Entity Data Model.
Create Entity Data Model
Right click on your model folder and click new, select ADO.NET Entity Data Model. Follow the steps given. Once you have done the process , you can see the edmx file and other files in your model folder. Here I gave Dashboard for our Entity data model name. Now you can see a file with edmx extension have been created.
Now we will create our Web API controller.
Create Web API Controller
To create a Web API controller, just right click on your controller folder and click Add, Controller, then select Web API 2 Controller with actions, using Entity Framework.
Figure: Web API 2 Controller With Actions Using Entity Framework
Now select tblTag (WebAPIWithHttpClient.Models) as our Model class and TrialsDBEntities (WebAPIWithHttpClient.Models) as data context class. This time we will select controller with async actions.
Figure: Web API Controller With Async Actions
As you can see it has been given the name of our controller astblTags. Here, I am not going to change that, if you wish to change, you can do that.
Now you will be given the following codes in our new Web API controller.
As you can see, we have actions for,
So the coding part to fetch the data from the database is ready, now we need to check whether our Web API is ready for action!. To check that, you just need to run the URL: http://localhost:7967/api/tbltags. Here, tblTags is our Web API controller name. I hope you get the data as a result.
Figure: Web_API_Result
As of now our Web API application is ready, and we have just tested whether it is working or not. Now we can move on to create a console application where we can consume this Web API with the help of HttpClient. So shall we do that?
Create Console Application To Consume Web API
To create a console application, Click File, New, then click Windows and then select Console application, Name your application, then click OK.
Figure: Console Application
I hope now you have a class called Program.cs with the following codes.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace WebAPIWithHttpClientConsumer
- {
- class Program
- {
- static void Main(string[] args)
- {}
- }
- }
Now we will start our coding, We will create a class calledtblTag with some properties so that we can use those when we need.
- public class tblTag
- {
- public int tagId
- {
- get;
- set;
- }
- public string tagName
- {
- get;
- set;
- }
- public string tagDescription
- {
- get;
- set;
- }
- }
To get started using the classHttpClient, you must import the namespace as follows.
Once you have imported the namespaces, we will set our HttpClient and the properties as follows.
- HttpClient cons = new HttpClient();
- cons.BaseAddress = new Uri("http://localhost:7967/");
- cons.DefaultRequestHeaders.Accept.Clear();
- cons.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
As you can see we are just giving the base address of our API and setting the response header. Now we will create an asyn action to get the data from our database by calling our Web API.
Get operation using HttpClient
The following is the definition of MyAPIGet function.
- static async Task MyAPIGet(HttpClient cons)
- {
- using(cons)
- {
- HttpResponseMessage res = await cons.GetAsync("api/tblTags/2");
- res.EnsureSuccessStatusCode();
- if (res.IsSuccessStatusCode)
- {
- tblTag tag = await res.Content.ReadAsAsync < tblTag > ();
- Console.WriteLine("\n");
- Console.WriteLine("---------------------Calling Get Operation------------------------");
- Console.WriteLine("\n");
- Console.WriteLine("tagId tagName tagDescription");
- Console.WriteLine("-----------------------------------------------------------");
- Console.WriteLine("{0}\t{1}\t\t{2}", tag.tagId, tag.tagName, tag.tagDescription);
- Console.ReadLine();
- }
- }
- }
Here, res.EnsureSuccessStatusCode(); ensure that it throws errors if we get any. If you don’t need to throw the errors, please remove this line of code. If the asyn call is success, the value inIsSuccessStatusCode will be true.
Now when you run the above code, there are chances to get an error as follows.
Error CS1061 ‘HttpContent’ does not contain a definition for ‘ReadAsAsync’ and no extension method ‘ReadAsAsync’ accepting a first argument of type ‘HttpContent’ could be found (are you missing a using directive or an assembly reference?)
This is just because of theReadAsAsync is a part ofSystem.Net.Http.Formatting.dll which we have not added to our application as a reference yet. Now we will do that? Sounds OK?
Just right click on the references and click add reference, then click browse andsearch for System.Net.Http.Formatting.dll, click OK
Figure: Add References
Please add Newtonsoft.Json also. Now let us run our project and see the output.
Figure: Web_API_Consumer_Get_Output
Now shall we create a function for updating the record? Yes, we are going to create a function with ‘Put’ request. Please copy and paste preceding code for that.
Put operation using HttpClient
- static async Task MyAPIPut(HttpClient cons)
- {
- using(cons)
- {
- HttpResponseMessage res = await cons.GetAsync("api/tblTags/2");
- res.EnsureSuccessStatusCode();
- if (res.IsSuccessStatusCode)
- {
- tblTag tag = await res.Content.ReadAsAsync < tblTag > ();
- tag.tagName = "New Tag";
- res = await cons.PutAsJsonAsync("api/tblTags/2", tag);
- Console.WriteLine("\n");
- Console.WriteLine("\n");
- Console.WriteLine("-----------------------------------------------------------");
- Console.WriteLine("------------------Calling Put Operation--------------------");
- Console.WriteLine("\n");
- Console.WriteLine("\n");
- Console.WriteLine("-----------------------------------------------------------");
- Console.WriteLine("tagId tagName tagDescription");
- Console.WriteLine("-----------------------------------------------------------");
- Console.WriteLine("{0}\t{1}\t\t{2}", tag.tagId, tag.tagName, tag.tagDescription);
- Console.WriteLine("\n");
- Console.WriteLine("\n");
- Console.WriteLine("-----------------------------------------------------------");
- Console.ReadLine();
- }
- }
- }
As you can see we are just updating the record as below once we get the response from await cons.GetAsync(“api/tblTags/2”) .
- tag.tagName = "New Tag";
- res = await cons.PutAsJsonAsync("api/tblTags/2", tag);
Now again run your application, and check whether the tag name has been changed to ‘New Tag’.
Figure: Web_API_Consumer_Put_Output
Now did you see that your tag name has been changed? If yes, we are ready to go for our next operation. Are you ready?
Delete operation using HttpClient
We will follow the same procedure for delete operation too. Please see the code for delete operation below.
- async Task MyAPIDelete(HttpClient cons)
- {
- using(cons)
- {
- HttpResponseMessage res = await cons.GetAsync("api/tblTags/2");
- res.EnsureSuccessStatusCode();
- if (res.IsSuccessStatusCode)
- {
- res = await cons.DeleteAsync("api/tblTags/2");
- Console.WriteLine("\n");
- Console.WriteLine("\n");
- Console.WriteLine("-----------------------------------------------------------");
- Console.WriteLine("------------------Calling Delete Operation--------------------");
- Console.WriteLine("------------------Deleted-------------------");
- Console.ReadLine();
- }
- }
- }
To delete a record we use res = await cons.DeleteAsync(“api/tblTags/2”); method. Now run your application and see the result.
Figure: Web_API_Consumer_Delete_Output
What action is pending now? Yes, it is Post.
Post operation using HttpClient
Please add the below function to your project for the post operation.
- static async Task MyAPIPost(HttpClient cons)
- {
- using(cons)
- {
- var tag = new tblTag
- {
- tagName = "jQuery", tagDescription = "This tag is all about jQuery"
- };
- HttpResponseMessage res = await cons.PostAsJsonAsync("api/tblTags", tag);
- res.EnsureSuccessStatusCode();
- if (res.IsSuccessStatusCode)
- {
- Console.WriteLine("\n");
- Console.WriteLine("\n");
- Console.WriteLine("-----------------------------------------------------------");
- Console.WriteLine("------------------Calling Post Operation--------------------");
- Console.WriteLine("------------------Created Successfully--------------------");
- }
- }
- }
We are just creating a new tblTag and assigning some values, once the object is ready we are calling the method PostAsJsonAsync as follows.
- var tag = new tblTag { tagName = "jQuery", tagDescription = "This tag is all about jQuery" };
- HttpResponseMessage res = await cons.PostAsJsonAsync("api/tblTags", tag);
As you have noticed, I have not provided thetagId in the object, do yo know why? I have already setIdentity Specification with Identity Increment 1 in my tabletblTags in SQL database.
Now we will see the output. Shall we?
Figure: Web_API_Consumer_Post_Output
We have done everything! That’s fantastic, right? Happy coding.
You can always use WebClient also for this requirement, I will share that in another article.
Conclusion
Did I miss anything that you may think is needed? Did you try Web API yet? Have you ever wanted to call a Web API from server itself or from any console application? Did you find this post useful? I hope you liked this article. Please share with me your valuable suggestions and feedback.
Your turn. What do you think?
A blog isn’t a blog without comments, but do try to stay on topic. If you have a question unrelated to this post, you’re better off posting it on C# Corner, Code Project, Stack Overflow, ASP.NET Forum instead of commenting here. Tweet or email me a link to your question there and I’ll definitely try to help if I can.
Please see this article in my blog here.
Read more articles on ASP.NET: