Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Web API With HttpClient or Consume Web API From Console Application

DZone's Guide to

Web API With HttpClient or Consume Web API From Console Application

In this article, we are going to learn how to call Web API using HttpClient. Normally, we call a Web API either from jQuery Ajax or from Angular JS, right? Recently, I came across a need for calling our Web API from the server side itself. Let me show you how it's done.

· Web Dev Zone
Free Resource

Add user login and MFA to your next project in minutes. Create a free Okta developer account, drop in one of our SDKs to your application and get back to building.

In this article, we are going to learn how to call Web API using HttpClient. Normally, we call a Web API either from jQuery Ajax or from Angular JS, right? Recently, I came across a need for 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, while the other is a console application where I consume my Web API. Sound good?

I am using Visual Studio 2015. You can check out tips/tricks/blogs about these mentioned technologies from the links given below.

  • MVC Tips, Tricks, Blogs
  • Web API Tips, Tricks, Blogs
  • Now we will go and create our application. I hope this is helpful.

    Download the Source Code

    You can always download the source code here.

  • Web API Application
  • Web API Consumer
  • Background

    We all use Web API in our applications to implement HTTP services. HTTP services are much simpler if we use Web API, but, the fact is, the benefits of using Web API are not limited to that. Previously, we've used WCF services instead of Web API, when we were working with endpoints. Here, I am going to explain an important feature of Web API that allows us to call Web API from our server itself instead of using an Ajax Call. That is pretty cool, right? Now, we will create our application.

    First, we will create our Web API application.

    Creating Web API Application

    Click File-> New-> Project 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.

    Empty Template With MVC And Web API Folders

    Empty Template With MVC And Web API Folders

    Once you click OK, a project with an MVC-like folder structure with core references will be created for you.

    Folder Structure And References For Empty MVC Project

    Folder Structure And References For Empty MVC Project

    Using the Code

    We will set up our database first so that we can create an 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. As of now. I am going to create the table tblTags.

    Create Tables in Database

    Below is the query to create the table tblTags.

    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 into the tables now?

    Insert Data into Table

    You can use the below query to insert the data into the table tblTags.

    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 create an ADO.NET Entity Data Model.

    Create Entity Data Model

    Right click on your model folder and click new, then select ADO.NET Entity Data Model. Follow the steps given. Once you have completed the processes, you can see the edmx file and other files in your model folder. Here, I provided Dashboard for our Entity data model name. Now, you can see a file with an edmx extension has been created.

    Now let's 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 -> Select Web API 2 controller with actions, using Entity Framework.

    Web API 2 Controller With Actions Using Entity Framework

    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 to use a controller with async actions.

    Web API Controller With Async Actions

    Web API Controller With Async Actions

    As you can see, our controller has been given the name of tblTags. Here, I am not going to change that... if you wish to change it, you can do that.

    Now, we will be given the following code in our new Web API controller.

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Web.Http;
    using System.Web.Http.Description;
    using WebAPIWithHttpClient.Models;
    
    namespace WebAPIWithHttpClient.Controllers
    {
        public class tblTagsController : ApiController
        {
            private TrialsDBEntities db = new TrialsDBEntities();
    
            // GET: api/tblTags
            public IQueryable<tblTag> GettblTags()
            {
                return db.tblTags;
            }
    
            // GET: api/tblTags/5
            [ResponseType(typeof(tblTag))]
            public async Task<IHttpActionResult> GettblTag(int id)
            {
                tblTag tblTag = await db.tblTags.FindAsync(id);
                if (tblTag == null)
                {
                    return NotFound();
                }
    
                return Ok(tblTag);
            }
    
            // PUT: api/tblTags/5
            [ResponseType(typeof(void))]
            public async Task<IHttpActionResult> PuttblTag(int id, tblTag tblTag)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                if (id != tblTag.tagId)
                {
                    return BadRequest();
                }
    
                db.Entry(tblTag).State = EntityState.Modified;
    
                try
                {
                    await db.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!tblTagExists(id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
    
                return StatusCode(HttpStatusCode.NoContent);
            }
    
            // POST: api/tblTags
            [ResponseType(typeof(tblTag))]
            public async Task<IHttpActionResult> PosttblTag(tblTag tblTag)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                db.tblTags.Add(tblTag);
                await db.SaveChangesAsync();
    
                return CreatedAtRoute("DefaultApi", new { id = tblTag.tagId }, tblTag);
            }
    
            // DELETE: api/tblTags/5
            [ResponseType(typeof(tblTag))]
            public async Task<IHttpActionResult> DeletetblTag(int id)
            {
                tblTag tblTag = await db.tblTags.FindAsync(id);
                if (tblTag == null)
                {
                    return NotFound();
                }
    
                db.tblTags.Remove(tblTag);
                await db.SaveChangesAsync();
    
                return Ok(tblTag);
            }
    
            protected override void Dispose(bool disposing)
            {
                if (disposing)
                {
                    db.Dispose();
                }
                base.Dispose(disposing);
            }
    
            private bool tblTagExists(int id)
            {
                return db.tblTags.Count(e => e.tagId == id) > 0;
            }
        }
    }

    As you can see, we have actions for:

  • Get
  • Post
  • Put
  • Delete
  • So, the coding part to fetch the data from the database is ready, and now we need to check whether or not 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.

    Web_API_Result

    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 -> Click Windows -> Select Console application -> Name your application -> OK

    Console Application

    Console Application

    I hope now you have a class called Program.cs with the below 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. Let's create a class called tblTag with some properties so that we can use those when necessary.

    public class tblTag
        {
            public int tagId { get; set; }
            public string tagName { get; set; }
            public string tagDescription { get; set; }
        }
    

    To get started using the class HttpClient, you must import the namespace as follows.

    using System.Net.Http;

    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 async action to get the data from our database by calling our Web API.

    Get Operation Using HttpClient

    MyAPIGet(cons).Wait();

    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 errors, please remove this line of code. If the async call is a success, the value in IsSuccessStatusCode 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 the ReadAsAsync is a part of System.Net.Http.Formatting.dll which we have not added to our application as a reference yet. Now, we will do that. Sound OK?

    Just right click on the references and click add reference -> Click browse -> search for System.Net.Http.Formatting.dll -> Click OK.

    Add References

    Add References

    Please add Newtonsoft.Json also. Now, let's run our project and see our output.

    Web_API_Consumer_Get_Output

    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 the 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, run your application again and check whether the tag name has been changed to 'New Tag'.

    Web_API_Consumer_Put_Output

    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 uses res = await cons.DeleteAsync(“api/tblTags/2”); method. Now, run your application and see the result.

    Web_API_Consumer_Delete_Output

    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 will call 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 the tagId in the object... do you know why? I have already set Identity Specification with Identity Increment 1 in my table tblTags in SQL database.

    Now, let's see the output. Shall we?

    Web_API_Consumer_Post_Output

    Web_API_Consumer_Post_Output

    We have done everything! That’s fantastic, right? Happy coding!

    You can also always use WebClient for this requirement... I will share how in another article.

    Launch your application faster with Okta’s user management API. Register today for the free forever developer edition!

    Topics:
    c# ,mvc ,httpclient

    Published at DZone with permission of Sibeesh Venu, DZone MVB. See the original article here.

    Opinions expressed by DZone contributors are their own.

    {{ parent.title || parent.header.title}}

    {{ parent.tldr }}

    {{ parent.urlSource.name }}