Consuming "Dallas" OData with Managed Code
This topic describes how to consume data from “Dallas” with an OData endpoint in applications using managed code.
Introduction
“Dallas” is in its third Community Technology Preview (CTP). CTP3 introduces live OData services. To learn more about the differences between CTP3 OData based services and CTP2 based services visit the “Dallas” team blog.
Accessing “Dallas” OData requires adding a “service reference” to your Visual Studio project. Service references are specific to particular datasets. The code in a service reference should not be modified as modification could result in improper functioning and side effects. Additionally, modifications will be overwritten whenever your service reference is refreshed. If accessing multiple data sources you need to add a service reference for each data source.
Prerequisites
This section assumes that you have a “Dallas” account and have completed Lessons 1 through 3 in the section Working with "Dallas" Accounts and Subscriptions and are familiar with the “Dallas” Marketplace and Service Explorer. You also need a subscription to InfoGroup’s InfoUSA New, Out-Of-Business and Historical Businesses - InfoUSA CTP3 service.
Step 1: Starting Your Project
-
Start Visual Studio as an Administrator
-
Right click Visual Studio in your Start Menu and select Run as administrator.
-
When asked if you want to allow this program (devenv.exe) to make changes to your computer click Yes.
-
Right click Visual Studio in your Start Menu and select Run as administrator.
-
On the Visual Studio Start Page select New Project.
-
From the New Project dialog box select C# Console Application. Give your project a meaningful name. For example, for this project you could name it InfoUSABusinessData. Then click OK.
-
Add the following using statement to Program.cs.
Step 2: Adding a Service Reference to Your Application
After starting Visual Studio as an administrator and creating a new console application (Step 1) add the service reference for the data you want to consume.
-
Sign in to your Windows Live Id.
-
Get the URL for the service you want to use.
-
Go to the “Dallas” Marketplace and select the Subscriptions tab.
-
Find the InfoUSA New, Out-Of-Business and Historical Businesses - InfoUSA service and click Click here to explore the dataset.
-
Scroll to the bottom of the page and find the text Create client classes by adding a service reference in Microsoft Visual Studio. Copy the link below it to your clipboard.

-
Go to the “Dallas” Marketplace and select the Subscriptions tab.
-
Add a service reference to your Visual Studio project
-
Return to your Visual Studio project. In Solution Explorer right click References. Select Add Service Reference… from the dropdown menu.
Warning This only works in Microsoft® Visual Studio. 
-
Paste the URL you copied to your clipboard above into the Address dropdown. Click Go. Wait a few moments for the Services text box to populate with the services available to your project.
-
Click the Namespace: textbox. Give it a meaningful namespace name. For example, InfoUSABusinesses. Click OK.
This adds a Service Reference node to your project in Solution Explorer with this service reference under it.
In the image below the red oval is the URL you pasted in for your service, the blue oval is the name of the service available at this URL, and the green oval is the namespace name you create.
-
Return to your Visual Studio project. In Solution Explorer right click References. Select Add Service Reference… from the dropdown menu.
-
Add the service reference to your code.
-
Open Program.cs in the Visual Studio code window.
-
Add the following using statement which makes your service reference accessible to your application.
Author's Note: InfoUSABusinessData is the name you chose as your project name/namespace. InfoUSABusinesses is the namespace name you chose when you added the service reference.
-
Open Program.cs in the Visual Studio code window.
Step 3: Consuming OData with Managed Code
-
Within your project’s namespace create a public class,
GetBusinessData. This class consumes the business data from the InfoUSA New, Out-of-Business and Historical Bussinesses – InfoUSA service. -
Create two private variables for your class.
-
A Uri to the service and a service container that stores your credentials in service context.
To find the service container name for your subscription, in Visual Studio double click your service reference namespace in Solution Explorer. This opens Object Explorer. Select and expand your service reference namespace to reveal the series types and service container type for your subscription.
For the InfoUSA service you are using for this project the container type name is InfoUSAHistoricalBusinessContainer, circled in red in the following screenshot.
-
A Uri to the service and a service container that stores your credentials in service context.
-
Create a constructor for your GetBusinessData class.
The constructor initializes the class’s private variables and creates credentials for the user.
TheserviceUriis the https link to your service which you copied to your clipboard in Step 2.2.c above. Thecontextis the container for this service. It derives from DataServiceContext in the System.Data.Services.Client namespace and contains, among other things, your credentials.
public GetBusinessData() { serviceUri = new Uri(SERVICE_URI); // SERVICE_URI is the URL you copied to your clipboard in Step 2.2 context = new InfoUSAHistoricalBusinessesContainer(serviceUri); context.Credentials = new NetworkCredential(USER_ID, // Your Live Id SECURE_ACCOUNT_KEY); // Your “Dallas” Account Key }
-
Create a public method within your GetBusinessData class that returns a generic list. For our program the generic type is Nixie, though it could be any of the data series from this service (inside blue rectangles in the previous screenshot (Historical_Business, NewBusiness, or Nixie).
This method queries the Nixie series. If the query is successful the resulting generic list is returned. If the query is unsuccessful for any reason an error message is displayed and null is returned.
The query can be any LINQ query and may optionally include thepublic IList<Nixie> getData() { IEnumerable<Nixie> query; query = from c in context.Nixie select c; try { return query.ToList(); } catch (Exception e) { Console.WriteLine("ERROR: {0} ", e.Message); return null; // Return null if an exception is thrown } }
wherefilter and/ororderby. For more information on LINQ queries see LINQ Query Expressions (C# Programming Guide).
The following query filters for CompanyName and State, then sorts the results in ascending order by ZipCode.
-
Write the code in Main() that will utilize your GetBusinessData class to obtain the data and then display the results.
In Visual Basic there is no equivalent to the C# expressionstatic void Main(string[] args) { GetBusinessData busData = new GetBusinessData(); // create an instance of your class IList<Nixie> dataList = busData.getData(); // populate your generic list with your query results if (dataList != null) // getData returns null if an exception is thrown. { // Display column headers Console.WriteLine("{0,-20} {1,10} {2,-30} {3,10}", "City", "Zip Code", "Business Name", "Phone"); Console.WriteLine("{0,-20} {1,10} {2,-30} {3,10}", "--------------------", "----- ----", "------------------------------", "----------"); // For each item in the list display selected fields foreach (Nixie d in dataList) Console.WriteLine("{0,-20} {1,5}{2,5} {3,-30} {4,10}", d.City, // pad left with 0 for zips < 10000 d.ZipCode.ToString().PadLeft(5, '0'), // if Zip4 is unknown print nothing // else pad left with 0’s for Zip4 < 1000 d.Zip4 == null ? null : "-" + Zip4.ToString().PadLeft(4,'0'), d.CompanyName, d.Phone); } // No action in Main() if query failed. The exception is handled in getData() // Pause until the user taps a key Console.Write("Tap any key to exit program. "); Console.ReadKey(); }
booleaExpression ? returnValueIfTrue : returnValueIfFalseso you need to create the following function to handle the Zip4 field neatly.
Function GetZip4(ByVal Zip4) As String If Zip4 Is Nothing Then GetZip4 = " " ' if no Zip+4 return 5 spaces Else GetZip4 = "-" + Zip4.ToString.PadLeft(4, "0"c) ' return "-" plus Zip+4 padded left with "0" for values < 1000 End If End Function
The Completed Program
The following C# code is the completed program.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; // needed for authentication using InfoUSABusinessData.InfoUSABusinesses; // RESTful proxy to data namespace InfoUSABusinessData { //------------------------------------------------- class Program { static void Main(string[] args) { IList<Nixie> dataList; // Nixie is a series in InfoUSABusinesses namespace (see Object Browser for others) GetBusinessData busData = new GetBusinessData(); dataList = busData.getData(); if (dataList != null) // getData returns null if an exception is thrown. { // Display column headers Console.WriteLine("{0,-20} {1,10} {2,-30} {3,10}", "City", "Zip Code", "Business Name", "Phone"); Console.WriteLine("{0,-20} {1,10} {2,-30} {3,10}", "--------------------", "----- ----", "------------------------------", "----------"); // For each item in the list display selected fields foreach (Nixie d in dataList) Console.WriteLine("{0,-20} {1,5}{2,5} {3,-30} {4,10}", d.City, // ZipCode < 10000 pad left with 0s to keep five digits d.ZipCode.ToString().PadLeft(5, '0'), // Zip4 is unknown print nothing // Zip4 < 1000 pad left with 0s to keep four digits d.Zip4 == null ? null : "-" + d.Zip4.ToString().PadLeft(4,'0'), d.CompanyName, d.Phone); } // No action in Main() if query failed. The exception is handled in getData() // Pause until the user taps a key Console.Write("Tap any key to exit program. "); Console.ReadKey(); } } //------------------------------------------------- class GetBusinessData { // These constants should be used for this demo only // In a production environment you would write code for the user to input their id values OR // to retrieve it from a database. // The account key should be encrypted to keep it secure. Do not pass the encrypted key to Dallas. // USER_ID is your Live Id, and // SECURE_ACCOUNT_KEY is your account key (found at the Marketplace under the Account keys tab) private const string USER_ID = "<your Live Id>"; private const string SECURE_ACCOUNT_KEY = "<your Dallas Account Key>"; private const string SERVICE_URI = "<the URL you pasted to your clipboard in Step 2.2>"; private InfoUSAHistoricalBusinessesContainer context; // see InfoUSABusinesses in Object Explorer for container name private Uri serviceUri; public GetBusinessData() { serviceUri = new Uri(SERVICE_URI); context = new InfoUSAHistoricalBusinessesContainer(serviceUri); context.Credentials = new NetworkCredential(USER_ID, SECURE_ACCOUNT_KEY); } public IList<Nixie> getData() { IEnumerable<Nixie> query; query = from c in context.Nixie where c.CompanyName != "" && c.State == "DE" // no empty company names and from Delaware only orderby c.ZipCode Ascending select c; try { return query.ToList(); } catch (Exception e) { Console.WriteLine("ERROR: {0} ", e.Message); return null; // Return null if an exception is thrown } } } }
Had this been an ASP.NET web page instead of a Console Application, the results could have easily been bound to a DataGrid using the following code in place of the foreach loop above:
myDataGridView.DataSource = dataList;