Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Bing Local Business Search API

0.00/5 (No votes)
23 Jan 2019CPOL2 min read 4.4K  
Getting started with Bing Local Business Search

Introduction

Bing Local Business Search finds businesses within a specified geographical area. The API is accessible from any code language that can send a REST request. The request query specifies a business name and location, for example, 'q=auto repair in Olympia, WA'. The area to search can also be set using circular or square geographical boundaries, or the X-Search-Location header. The results-by-category option can use reverse IP location or GPS coordinates of the caller to return localized results for various types of business.

Results include a URL for the business website and display text, phone number, and geographical location, including: GPS coordinates, city, street address.

Background

The Bing Local Search endpoint extends the Bing Search API.

Using the Code

The code to find localized businesses has two parts:

  1. Construct and send a REST request to the endpoint: https://api.cognitive.microsoft.com/bing/v7.0/localbusinesses/search
  2. Parse the JSON results.

To send a WebRequest to the Local Business Search endpoint, you need an access key available with a Cognitive Services API account for the Bing Search APIs. The free trial is sufficient for testing. For production, when you create the resource in Azure portal, select S10 level. See also Cognitive Services Pricing - Bing Search API.

The following code constructs a request, sends it to the endpoint, and reads the results. Currently, Local Business Search supports only the English language US market.

C#
// Assign a valid access key.
const string accessKey = "Your-Access-Key";

const string uriBase = "https://api.cognitive.microsoft.com/bing/v7.0/localbusinesses/search";

const string searchTerm = "auto repair in Olympia, WA";

// Concatenate the uriBase and query for the request.
var uriQuery = uriBase + "?q=" + Uri.EscapeDataString(searchQuery) + mkt=en-us;

// Create the request, and add the access key header.
WebRequest request = HttpWebRequest.Create(uriQuery);
request.Headers["Ocp-Apim-Subscription-Key"] = accessKey;

// Get the results.
HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result;
string json = new StreamReader(response.GetResponseStream()).ReadToEnd();

Use the following structure to contain the results of a request and headers.

C#
// Search results as JSON and relevant headers
struct SearchResult
{
   public String jsonResult;
   public Dictionary<String, String> relevantHeaders;
}

Parse the JSON text using the following method from the Microsoft documentation.

C#
/// <summary>
/// Formats the given JSON string by adding line breaks and indents.
/// </summary>
/// <param name="json">The raw JSON string to format.</param>
/// <returns>The formatted JSON string.</returns>
static string JsonPrettyPrint(string json)
{
    if (string.IsNullOrEmpty(json))
        return string.Empty;

    json = json.Replace(Environment.NewLine, "").Replace("\t", "");

    StringBuilder sb = new StringBuilder();
    bool quote = false;
    bool ignore = false;
    int offset = 0;
    int indentLength = 3;

    foreach (char ch in json)
    {
        switch (ch)
        {
            case '"':
                if (!ignore) quote = !quote;
                break;
            case '\'':
                if (quote) ignore = !ignore;
                break;
        }

        if (quote)
            sb.Append(ch);
        else
        {
            switch (ch)
            {
                case '{':
                case '[':
                    sb.Append(ch);
                    sb.Append(Environment.NewLine);
                    sb.Append(new string(' ', ++offset * indentLength));
                    break;
                case '}':
                case ']':
                    sb.Append(Environment.NewLine);
                    sb.Append(new string(' ', --offset * indentLength));
                    sb.Append(ch);
                    break;
                case ',':
                    sb.Append(ch);
                    sb.Append(Environment.NewLine);
                    sb.Append(new string(' ', offset * indentLength));
                    break;
                case ':':
                    sb.Append(ch);
                    sb.Append(' ');
                    break;
                default:
                    if (ch != ' ') sb.Append(ch);
                    break;
            }
        }
    }

    return sb.ToString().Trim();
}

Run the Code in Console Application

The complete code is shown in the following block:

C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;

namespace LocalBusinessSrchCshp
{
    class Program
    {
        // **********************************************
        // *** Update or verify the following values. ***
        // **********************************************

        // Replace the accessKey string value with your valid access key.
        const string accessKey = "Your-Access-Key";
        const string uriBase = "https://api.cognitive.microsoft.com/bing/v7.0/localbusinesses/search";

        const string searchTerm = "auto repair in Olympia, WA";

        // Returns search results including relevant headers
        struct SearchResult
        {
            public String jsonResult;
            public Dictionary<String, String> relevantHeaders;
        }

        static void Main()
        {
            Console.OutputEncoding = System.Text.Encoding.UTF8;
            Console.WriteLine("Searching locally for: " + searchTerm);

            SearchResult result = BingLocalSearch(searchTerm, accessKey);

            Console.WriteLine("\nRelevant HTTP Headers:\n");
            foreach (var header in result.relevantHeaders)
                Console.WriteLine(header.Key + ": " + header.Value);

            Console.WriteLine("\nJSON Response:\n");
            Console.WriteLine(JsonPrettyPrint(result.jsonResult));

            Console.Write("\nPress Enter to exit ");
            Console.ReadLine();
        }

        /// <summary>
        /// Runs a Bing Local business search and returns the results as a SearchResult.
        /// </summary>
        static SearchResult BingLocalSearch(string searchQuery, string key)
        {
            // Construct the URI of the search request
            var uriQuery = uriBase + "?q=" + Uri.EscapeDataString(searchQuery) + "&mkt=en-us";

            // Run the Web request and get the response
            WebRequest request = HttpWebRequest.Create(uriQuery);
            request.Headers["Ocp-Apim-Subscription-Key"] = accessKey; 

            HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result;
            string json = new StreamReader(response.GetResponseStream()).ReadToEnd();

            // Create result object for return
            var searchResult = new SearchResult();
            searchResult.jsonResult = json;
            searchResult.relevantHeaders = new Dictionary<String, String>();

            // Extract Bing HTTP headers
            foreach (String header in response.Headers)
            {
                if (header.StartsWith("BingAPIs-") || header.StartsWith("X-MSEdge-"))
                    searchResult.relevantHeaders[header] = response.Headers[header];
            }

            return searchResult;
        }

        /// <summary>
        /// Formats the given JSON string by adding line breaks and indents.
        /// </summary>
        /// <param name="json">The raw JSON string to format.</param>
        /// <returns>The formatted JSON string.</returns>
        static string JsonPrettyPrint(string json)
        {
            if (string.IsNullOrEmpty(json))
                return string.Empty;

            json = json.Replace(Environment.NewLine, "").Replace("\t", "");

            StringBuilder sb = new StringBuilder();
            bool quote = false;
            bool ignore = false;
            int offset = 0;
            int indentLength = 3;

            foreach (char ch in json)
            {
                switch (ch)
                {
                    case '"':
                        if (!ignore) quote = !quote;
                        break;
                    case '\'':
                        if (quote) ignore = !ignore;
                        break;
                }

                if (quote)
                    sb.Append(ch);
                else
                {
                    switch (ch)
                    {
                        case '{':
                        case '[':
                            sb.Append(ch);
                            sb.Append(Environment.NewLine);
                            sb.Append(new string(' ', ++offset * indentLength));
                            break;
                        case '}':
                        case ']':
                            sb.Append(Environment.NewLine);
                            sb.Append(new string(' ', --offset * indentLength));
                            sb.Append(ch);
                            break;
                        case ',':
                            sb.Append(ch);
                            sb.Append(Environment.NewLine);
                            sb.Append(new string(' ', offset * indentLength));
                            break;
                        case ':':
                            sb.Append(ch);
                            sb.Append(' ');
                            break;
                        default:
                            if (ch != ' ') sb.Append(ch);
                            break;
                    }
                }
            }

            return sb.ToString().Trim();
        }
    }
}

Search Using Reverse IP and Radius

This method uses the X-Search-Location header and radius in meters to find businesses within a circular area around the user's location as determined by reverse IP. Make two small changes to the previous code as shown in the following block.

First, change the search terms, omitting the location:

C#
//const string searchTerm = "auto repair in Olympia, WA";
const string searchTerm = "auto repair";

Then, add the radius header and assign a value, 18,000 meters in this example.

C#
// Run the Web request and get the response
WebRequest request = HttpWebRequest.Create(uriQuery);
request.Headers["Ocp-Apim-Subscription-Key"] = accessKey;
request.Headers["re"] = "18,000m";

Run the modified application to get results.

Search Using Longitude/Latitude

Specify the search terms, omitting the location:

C#
//const string searchTerm = "auto repair in Olympia, WA";
const string searchTerm = "auto repair";

Add the longitude/latitude headers.

C#
// Run the Web request and get the response
WebRequest request = HttpWebRequest.Create(uriQuery);
request.Headers["Ocp-Apim-Subscription-Key"] = accessKey;
request.Headers["long"] = "47.642065";
request.Headers["lat"] = "-122.13061";

Run the modified application to get results.

History

  • Version 1.0.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)