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:
- Construct and send a REST request to the endpoint: https://api.cognitive.microsoft.com/bing/v7.0/localbusinesses/search
- 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.
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";
var uriQuery = uriBase + "?q=" + Uri.EscapeDataString(searchQuery) + mkt=en-us;
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();
Use the following structure to contain the results of a request and headers.
struct SearchResult
{
public String jsonResult;
public Dictionary<String, String> relevantHeaders;
}
Parse the JSON text using the following method from the Microsoft documentation.
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:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
namespace LocalBusinessSrchCshp
{
class Program
{
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";
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();
}
static SearchResult BingLocalSearch(string searchQuery, string key)
{
var uriQuery = uriBase + "?q=" + Uri.EscapeDataString(searchQuery) + "&mkt=en-us";
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();
var searchResult = new SearchResult();
searchResult.jsonResult = json;
searchResult.relevantHeaders = new Dictionary<String, String>();
foreach (String header in response.Headers)
{
if (header.StartsWith("BingAPIs-") || header.StartsWith("X-MSEdge-"))
searchResult.relevantHeaders[header] = response.Headers[header];
}
return searchResult;
}
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:
const string searchTerm = "auto repair";
Then, add the radius header and assign a value, 18,000 meters in this example.
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:
const string searchTerm = "auto repair";
Add the longitude/latitude headers.
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