Overview

Bing Image of the Day has become quite popular over the years, it comprises of essentially the most spectacular user-submitted images from all over the world which have been showcased on the Bing homepage for the past 5 years. I have absolutely loved the Bing Wallpaper of the day part of the Bing desktop application. Bing desktop app changes your wallpaper every day to Bing Image of the Day, which is pretty cool and gives you a peace of mind without having to change the wallpaper every day manually. The somewhat similar concept has been used in Windows Phone as well, where you can set the lock screen to the Bing Image of the Day.

I was so interested in the idea that I wanted to try out myself building an app to retrieve the Bing Image. I knew once I could retrieve the image, I had numerous possibilities going forward. I could save it and change my desktop after a certain duration of my choice, or set it as my lock screen just as a desktop wallpaper, you get my point, the key here is to get the Bing Image of the Day.

Fortunately, Bing has a REST API to retrieve a JSON string which contains the URL to the Bing Image, which we will be making use of. That is the easy part, now the hard part is to parse and retrieve the URL from the JSON string. I will be discussing in detail the different methods that can be used for parsing and how they can be used to extract the Bing Image URL.

Step 1. Retrieve the JSON string

The first step is to retrieve the JSON string from the Bing REST API endpoint. We retrieve the string using an HttpClient,we have an option of using Windows.Web.Http or System.Net.Http namespace.
I prefer to choose Windows.Web.Http.HttpClient for the simple reason that the System.Net.Http.HttpClient might get deprecated over time. Another reason is that System.Net.Http.HttpClient supports only .Net Languages, whereas Windows.Web.Http.HttpClient was written with the aim of consolidating all the HTTP APIs for different Windows Application Languages, and therefore it supports all the Windows Store application languages. For the avid readers here is a detailed comparison between the two.

// We can specify the region we want for the Bing Image of the Day.
string strRegion = "en-US";
string strBingImageURL = string.Format("http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n={0}&mkt={1}", _numOfImages, strRegion);
string strJSONString = "";

HttpClient client = new HttpClient();

// Using an Async call makes sure the app is responsive during the time the response is fetched.
// GetAsync sends an Async GET request to the Specified URI.
HttpResponseMessage response = await client.GetAsync(new Uri(strBingImageURL));

// Content property get or sets the content of a HTTP response message. 
// ReadAsStringAsync is a method of the HttpContent which asynchronously 
// reads the content of the HTTP Response and returns as a string.
strJSONString = await response.Content.ReadAsStringAsync();

Step 2. Parse the JSON string

Now we can parse the retrieved JSON string using 3 methods
• Using Windows.Data.Json (Native Way)
• Using LINQ-to-JSON API’s JObject from JSON.NET (Newtonsoft)
• Using dynamic object and DeserializeObject method JSON.NET (Newtonsoft)
JSON.Net has existed since long before Windows.Data.Json came into existence, however, Microsoft introduced Windows.Data.Json with native support for parsing JSON. To use JSON.NET, you need to add the Newtonsoft Nuget package, which adds an additional library dependency. I personally prefer the native way, however for the purpose of this app I have discussed both the ways of parsing the JSON string using both JSON.NET and Windows.Data.Json namespaces.

Retrieved JSON string:

{"images":[

    {"startdate":"20160719","fullstartdate":"201607190700","enddate":"20160720","url":"/az/hprichbg/rb/NeonMuseum_EN-US8131993872_1920x1080.jpg","urlbase":"/az/hprichbg/rb/NeonMuseum_EN-US8131993872","copyright":"Neon Museum, Las Vegas, Nevada (© Kerrick James/Getty Images)","copyrightlink":"http://www.bing.com/search?q=neon+museum&form=hpcapt&filters=HpDate:%2220160719_0700%22","wp":false,"hsh":"96d3e7bbe87ad583a17ef765ed935d8f","drk":1,"top":1,"bot":1,"hs":[]}
    ,
    {"startdate":"20160718","fullstartdate":"201607180700","enddate":"20160719","url":"/az/hprichbg/rb/DiamondHead_EN-US10119574903_1920x1080.jpg","urlbase":"/az/hprichbg/rb/DiamondHead_EN-US10119574903","copyright":"Aerial view of Diamond Head, O’ahu, Hawaii (© Biederbick & Rumpf/Offset)","copyrightlink":"http://www.bing.com/search?q=diamond+head+hawaii&form=hpcapt&filters=HpDate:%2220160718_0700%22","wp":true,"hsh":"1aff492416f5e2fcf6e898743154fbda","drk":1,"top":1,"bot":1,"hs":[]}
    ,
    {"startdate":"20160717","fullstartdate":"201607170700","enddate":"20160718","url":"/az/hprichbg/rb/MuizenbergSA_EN-US9176714978_1920x1080.jpg","urlbase":"/az/hprichbg/rb/MuizenbergSA_EN-US9176714978","copyright":"Beach huts in Muizenberg, South Africa (© Getty Images)","copyrightlink":"http://www.bing.com/search?q=Muizenberg,+South+Africa&form=hpcapt&filters=HpDate:%2220160717_0700%22","wp":true,"hsh":"8d4bf37f9d61ab103283005264b4b8cb","drk":1,"top":1,"bot":1,"hs":[]}

    ]

    ,"tooltips":{"loading":"Loading...","previous":"Previous image","next":"Next image","walle":"This image is not available to download as wallpaper.","walls":"Download this image. Use of this image is restricted to wallpaper only."}
}

Step 2a. Parsing JSON string using Windows.Data.Json:

This Method parses the fetched JSON string and retrieves the Image URLs using Microsoft Windows.Data.Json class. We use JsonObject that implements an IMap interface, which can help in manipulating the name/value pairs like a dictionary. We use JsonObject.TryParse method to parse the JSON string into a JSON value, it returns a boolean value, indicating success or failure. The integral part of the retrieval is jsonObject["images"].GetArray()[i].GetObject()["url"].GetString(). As seen in the above JSON string, we have a root object "images", it further has 3 arrays, which are equal to the number of images specified in Step 1. Each array has an object called url, which is the part of the url to the Bing Image. We retrieve url for each image and store it into a list.

// Parse using Windows.Data.Json.
JsonObject jsonObject;
bool boolParsed = JsonObject.TryParse(_strRawJSONString, out jsonObject);

if (boolParsed)
{
    for (int i = 0; i < _numOfImages; i++)
    {
       _lstBingImageURLs.Add(jsonObject["images"].GetArray()[i].GetObject()["url"].GetString());
    }
}

Step 2b. Parsing JSON string using LINQ-to-JSON API’s JObject:

This Method parses the fetched JSON string and retrieves the Image URLs using LINQ-to-JSON API’s JObject explicitly.We use this method when we don’t know the JSON structure ahead of time. This method is recommended if only one or two values from the whole JSON string are required.

// Parse using LINQ-to-JSON API's JObject explicitly.
JObject jResults = JObject.Parse(_strRawJSONString);
foreach (var image in jResults["images"])
{
    _lstBingImageURLs.Add((string)image["url"]);
}

Step 2c. Parsing JSON string using DeserializeObject and dynamic object

This Method parses the fetched JSON string and retrieves the Image URLs using DeserializeObject method. We use JsonConvert.DeserializeObject method when already know the JSON structure and the strongly typed class we want to deserialize into. We use dynamic object, as it saves us the trouble of declaring a specific class to hold the JSON object.

// Parse using DeserializeObject method.
for (int i = 0; i < _numOfImages; i++)
{
    _lstBingImageURLs.Add(Convert.ToString((JsonConvert.DeserializeObject<dynamic>(_strRawJSONString)).images[i].url));
}

Step 3. Display images on UI using BitmapImage

Each URL is converted into a Bitmap Image and added into the Stack Panel dynamically to display as an Image Object. BitmapImage class inherits from the BitmapSource class and is specialized BitmapSource that is optimized for loading images using XAML.

foreach (string url in _lstBingImageURLs)
{
    // We use the Image control to display an image on the UI.
    Image imgbingImage = new Image();
    var bingURL = "https://www.bing.com" + url;

    BitmapSource imgbingImageSource = new BitmapImage(new Uri(bingURL));
    imgbingImage.Source = imgbingImageSource;
    
    // Add the Image control to the Stack Panel
    spImages.Children.Add(imgbingImage);
}

Working Windows 10 UWP App

Here is the screenshot of the working Windows 10 UWP app, I have hosted the Visual Studio solution file with source code at Github Repository Bing-Image-JSON which you can use to experiment yourself. Windows 10 UWP Bing Image of the Day

Final note:

The source code at the Github repo contains the full detailed code, which you can use to experiment and follow along. If you still face any problems or have any questions, feel free to leave a comment and I will be happy to help. Cheers :)