Sample Console Application using Client Credentials

Download Sample Source

For applications that do not need to Authenticate the user because the app is not going to access user date, the application can use the OAuth Client Credential Flow. This uses the Client ID and Client Secret that the application developer registered on CodeProject.

Note: The demos use a pre-registered Client ID and Client Secret. For your apps, you will need to register your own. Information about registering a Client ID and Client Secret can be found here.

The following code demonstrates a C# console application that gets an Access Token using Client Credentials, and then queries the server for the first page of new C# Articles and the first page of new C# Questions.

Note: that the request is made using HTTPS. HTTP requests will fail.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
using Newtonsoft.Json;

namespace ConsoleApplication3
{
    class Program
    {
        /// The client information used to get the OAuth Access Token from the server.
        static string clientId     = "JkOnJ9zIQ1vWvP3FvsJVx-3iOnSd-6a-";
        static string clientSecret = "U_ZHCQackGJHW4-Jn4qfGce6JLV9qAKhJEGahyRHVpeYVWf_r8iSaSt4z6AZn8kC";

        // The server base address
        static string baseUrl      = "https://api.codeproject.com/";

        // this will hold the Access Token returned from the server.
        static string accessToken  = null;

        static void Main(string[] args)
        {
            Console.WriteLine("Starting ...");
            DoIt().Wait();
            Console.ReadLine();
        }

        /// <summary>
        /// This method does all the work to get an Access Token and read the first page of
        /// Articles from the server.
        /// </summary>
        /// <returns></returns>
        private static async Task<int> DoIt()
        {
            // Get the Access Token.
            accessToken  = await GetAccessToken();
            Console.WriteLine( accessToken != null ? "Got Token" : "No Token found");

            // Get the Articles
            Console.WriteLine();
            Console.WriteLine("------ New C# Articles ------");

            dynamic response = await GetArticles(1, "c#");
            if (response.items != null)
            {
                var articles = (dynamic)response.items;
                foreach(dynamic article in articles)
                    Console.WriteLine("Title: {0}", article.title);
            }

            // Get the Articles
            Console.WriteLine();
            Console.WriteLine("------ New C# Questions ------");

            response = await GetQuestions(1, "c#");
            if (response.items != null)
            {
                var questions = (dynamic)response.items;
                foreach(dynamic question in questions)
                    Console.WriteLine("Title: {0}", question.title);
            }

            return 0;
        }

        /// <summary>
        /// This method uses the OAuth Client Credentials Flow to get an Access Token to provide
        /// Authorization to the APIs.
        /// </summary>
        /// <returns></returns>
        private static async Task<string> GetAccessToken()
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(baseUrl);

                // We want the response to be JSON.
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                // Build up the data to POST.
                List<keyvaluepair<string, string>> postData = new List<KeyValuePair<string, string>>();
                postData.Add(new KeyValuePair<string, string>("grant_type",    "client_credentials"));
                postData.Add(new KeyValuePair<string, string>("client_id",     clientId));
                postData.Add(new KeyValuePair<string, string>("client_secret", clientSecret));

                FormUrlEncodedContent content = new FormUrlEncodedContent(postData);

                // Post to the Server and parse the response.
                HttpResponseMessage response = await client.PostAsync("Token", content);
                string jsonString            = await response.Content.ReadAsStringAsync();
                object responseData          = JsonConvert.DeserializeObject(jsonString);

                // return the Access Token.
                return ((dynamic)responseData).access_token;
            }
        }

        /// <summary>
        /// Gets the page of Articles.
        /// </summary>
        /// <param name="page">The page to get.</param>
        /// <param name="tags">The tags to filter the articles with.</param>
        /// <returns>The page of articles.</returns>
        private static async Task<dynamic> GetArticles(int page, string tags)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(baseUrl);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                // Add the Authorization header with the AccessToken.
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);

                // create the URL string.
                string url = string.Format("v1/Articles?page={0}&tags={1}", page, HttpUtility.UrlEncode(tags));

                // make the request
                HttpResponseMessage response = await client.GetAsync(url);

                // parse the response and return the data.
                string jsonString = await response.Content.ReadAsStringAsync();
                object responseData = JsonConvert.DeserializeObject(jsonString);
                return (dynamic)responseData;
            }
        }

        /// <summary>
        /// Gets the page of Questions.
        /// </summary>
        /// <param name="page">The page to get.</param>
        /// <param name="tags">The tags to filter the articles with.</param>
        /// <returns>The page of articles.</returns>
        private static async Task<dynamic> GetQuestions(int page, string tags)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(baseUrl);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                // Add the Authorization header with the AccessToken.
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);

                // create the URL string.
                string url = string.Format("v1/Questions/new?page={0}&include={1}", page, HttpUtility.UrlEncode(tags));

                // make the request
                HttpResponseMessage response = await client.GetAsync(url);

                // parse the response and return the data.
                string jsonString = await response.Content.ReadAsStringAsync();
                object responseData = JsonConvert.DeserializeObject(jsonString);
                return (dynamic)responseData;
            }
        }
    }
}

This produces the output similar to:

Starting ...
Got Token
------ New C# Articles ------
Title: A Very Simple LINQ Example
Title: Bind Image Slider With a folder(Without Database) in ASP.NET C#
Title: Diving into OOP (Day 5): All About C# Access Modifiers
Title: Diving in OOP (Day 6): Understanding Enums in C# (A Practical Approach)
Title: Diving in OOP (Day 4):  Polymorphism and Inheritance (All About Abstract
...
------ New C# Questions ------
Title: how to fetch all the contents from web url
Title: C# How Can I Insert / Append An Image And Text Using Openxml?
Title: how to deblur and denoise an image
Title: convert datalist rows to pdf files (each row as a single pdf file)
Title: Send text to Viber with windows application
Title: How to get Dynamically Generated Controls value and store it into databse
...