Creating a Product Search Application Using the eBay SDK and Visual Basic .NET
Jeffrey P. McManus
Senior Manager of eBay Developer Relations
Summary: This article describes how to create a .NET Windows Forms application that searches eBay's product database using the eBay SDK, a .NET wrapper around eBay's XML-based API. The example application also shows a demonstration of data binding to an arbitrary XML document. (7 printed pages)
eBay provides an XML-based API for developers who want to integrate their applications with eBay. You can use the eBay API to list items for sale on eBay, perform searches, manage the bookkeeping associated with the end of a transaction, retrieve and leave feedback for buyers and sellers, and more.
The eBay SDK is a set of native .NET assemblies that wrap the XML-based API, making it easy for .NET developers to create applications that incorporate the eBay marketplace. The SDK is downloadable for free from http://developer.ebay.com. For this article, I've created a simple application that demonstrates the search capabilities of the eBay SDK in a Windows Forms application written in Visual Basic .NET. Although Visual Basic .NET was my choice for this project because of its ability to create great applications in a short amount of time, bear in mind that you can create eBay applications in any language.
I buy and sell things on eBay. When I'm using eBay.com, I find myself wanting to easily search for items quickly, without going through a browser interface. I also like to refine my searches, create different types of related searches, and go back to searches that have worked for me. So my goal was to create a handy search utility that enables me to search items easily and quickly, as well as return to searches I've performed recently.
I started by creating a Visual Basic .NET Windows Forms application with two forms. The first one, frmMain, enables search and displays search history, and is shown if Figure 1.
Figure 1. frmMain is the 'Search Bar' through which you enter your search terms.
The second form appears when you type something in the search box and click Enter (or double-click a previously-entered search term in the history list). This form is pretty simple. It is comprised of a Windows Forms toolbar with a single button and a DataGrid control. To view an item on eBay.com, you select an item in the search results grid and click on the Show Item toolbar button. The application then launches a browser window that shows the complete item details. This form is shown in Figure 2 below.
Figure 2. The item listing view shows the results of your search and allows you to launch the corresponding page of the eBay Web site to view an entry.
The secret behind all of these forms is the search capability provided by the eBay SDK. The search form contains code to create an eBay session, perform an eBay search, process the results of the search, and display the results in the results grid using data binding. Let's take a look at how this application works.
The layout of the forms and the accompanying code is straightforward, so I won't focus on that. When the application launches, it aligns itself to the edge of the screen so it's out of your way. Typing in a search keyword or selecting a pre-populated item from the list box kicks off a search. Any eBay SDK call first requires an instance of the eBay.SDK.API.ApiSession object. This object must be passed in to eBay with all the calls you make, so we'll create it.
Private Function CreateSession() As ApiSession Dim sess As ApiSession = New eBay.SDK.API.ApiSession With sess .Developer = _ ConfigurationSettings.AppSettings("DeveloperID") .Certificate = _ ConfigurationSettings.AppSettings("Certificate") .Application = _ ConfigurationSettings.AppSettings("ApplicationID") .RequestUserId = _ ConfigurationSettings.AppSettings("RequestUserID") .RequestPassword = _ ConfigurationSettings.AppSettings("RequestPassword") .Url = _ ConfigurationSettings.AppSettings("ServerUrl") End With Return sess End Function
Nothing too sophisticated here, just the eBay SDK version of some housekeeping. You might think of this as the equivalent of setting a connection string in a database-enabled application. DeveloperID, ApplicationID, and Certificate are string values that identify you and your application. RequestUserID and RequestPassword are asking for a valid eBay user name and password. The actual values you assign to the ApiSession object are contained in your application's App.Config file. There's an example App.Config file in the code download for this article. You'll need to get your own set of developer keys by signing up for free at http://developer.ebay.com/ and plugging them in to the configuration file for this application to work.
Now that you've got an ApiSession object, you can start making calls. To search eBay's product database, you use a GetSearchResultsCall object, which returns a typed collection of type IItemFoundCollection. To do a keyword search for products, you simply assign a string to the GetSearchResultsCall object's Query property.
Dim items As IItemFoundCollection search = New GetSearchResultsCall(CreateSession()) search.Query = txtQuery.Text Try items = search.GetSearchResults() Catch MsgBox("Sorry, your search returned no items.") End Try
It's possible that you'll want something more sophisticated than a straight keyword search. For example, you may want to search all the items listed by a particular seller. To do this, this application has the ability to parse out extended search commands the user types in. For example, if the user types seller: galexiegirl in the search box, the application retrieves only those items listed by the seller whose user ID is galexiegirl. Here's what the code looks like:
Private Sub MakeExtendedSearch(ByVal search As GetSearchResultsCall) Dim strQuery() As String strQuery = txtQuery.Text.Split(":") ' Parse extended query Select Case strQuery(0).ToLower() Case "seller" ' Search by seller search.IncludeSellers.Add(strQuery(1)) Case "highest" ' Return items with the specified maximum price search.HighestPrice = strQuery(1) Case "exclude" ' Filter out items listed by this seller search.ExcludeSellers.Add(strQuery(1)) Case Else MsgBox( _ "You used an extended search command I don't understand." & _ "Extended search commands are SELLER, HIGHEST, AND EXCLUDE") End Select If strQuery.Length > 2 Then ' Include keyword search if user supplied it search.Query = strQuery(2) End If End Sub
So, at this point the application has the ability to create a search object and execute a search, returning a collection of listed items for sale on the site. To display the data retrieved in your search, you have a choice. You can iterate through the IItemFoundCollection using a loop, and this collection is comprised of eBay.SDK.Model.Item objects that have properties that map to the attributes of an item for sale on eBay (like Title, Description, CurrentPrice, EndTime, and many more).
But there's another option. Let's say you want to display the results by binding them to a UI control such as System.Forms.DataGrid. To do data binding, you need an object that implements IList, and unfortunately, IItemFoundCollection doesn't implement IList. "Wait a minute," I hear you say. "Way up there, didn't you say that the SDK is just a wrapper around the XML-over-HTTP API? Shouldn't you be able to pull out some sort of XML-based object that implements IList?" Well, it does, and you can. Here's how.
The ability to drill down to the XML in the eBay SDK is implemented through event handlers. So, if you're using Visual Basic .NET, the first step is to move the declaration of your GetSearchResultsCall to the form level so you can declare it WithEvents.
Private WithEvents search As GetSearchResultsCall
The ability to easily handle events using the WithEvents keyword is a huge productivity boost for applications written in Visual Basic .NET. You can now handle the GetSearchResultsCall's OnReceiveResponseXml event. Our goal here is to capture the XML that's retrieved when we do a search, and convert that XML into a DataSet by way of the XmlNodeReader object.
Private Sub search_OnReceiveResponseXml(ByVal source As Object, _ ByVal e As eBay.SDK.API.FilterXmlEventArgs) _ Handles search.OnReceiveResponseXml Dim xd As Xml.XmlDocument = e.Xml Dim el As Xml.XmlElement ' We only care about items, so pull those out el = xd.SelectSingleNode("eBay/Search/Items") ' Convert your chunk o' XML into a DataSet ' via an XmlNodeReader for binding purposes Dim xReader As New Xml.XmlNodeReader(el) Dim ds As New DataSet ds.ReadXml(xReader) xReader.Close() ' Show results Dim f As New frmResults With f With .dgResults .DataSource() = ds.Tables(0).DefaultView End With .Show() End With End Sub
This is a roundabout process, but certainly far less involved than iterating through the IItemFoundCollection, picking out properties one property at a time, and painstakingly assigning them to elements of the data grid. This code also has the benefit of working as a kind of pattern. You could use this procedure or something like it to achieve data binding for virtually any XML document.
Now that we have our search results bound to a data grid, all that's left is to enable the user to navigate to the actual item in a browser if they desire. Since eBay items have direct URLs associated with them (and these URLs are returned in API searches), it should be a simple matter to extract the URL for an item selected in the data grid. We could write code to say, "Start up a Web browser to navigate to the URL value that I'm pretty sure is in column 3 of the currently-selected row in the grid."
However, there's one more wrinkle to contend with here. The data grid is populated with data that came from an XML document. Students of loosely-coupled systems will tell you that it's a bad idea to rely on the order of items in an XML document because that order may change in the future. So, rather than extracting the data from a fixed column, we'll be defensive here and iterate through the columns of the currently-selected row until we find one that begins with the string
http. That, we can safely assume, is the URL to the item page.
Dim x As Integer Dim str As String For x = 0 To dgResults.VisibleColumnCount str = dgResults(dgResults.CurrentRowIndex, x).ToString() If str.Length >= 4 Then ' Don't test null strings If str.Substring(0, 4) = "http" Then System.Diagnostics.Process.Start(str) End If End If Next
The System.Diagnostics.Process.Start trick is a good one to remember if you need to start up an application based on one of its document associations (in this case, it starts your default Web browser given a recognized URL).
There you have it. Searching for items on eBay is a good way to get started because it's a straightforward process, particularly if you use the SDK to do your heavy lifting for you. There are a number of additional items in the SDK that you can use to create or grow a business. There are more than forty calls today, with more being added all the time. Feel free to download the SDK at http://developer.ebay.com/ and try it out. If you build something cool, let us know!
Jeffrey P. McManus has been creating applications with Microsoft tools since the early cretaceous period. He is the author and co-author of six books on Visual Basic and .NET development, including Database Access with Visual Basic 6, VB .NET Developer's Guide to ASP.NET, XML and ADO.NET (with Chris Kinsman), and Database Access with Visual Basic .NET (with Jackie Goldstein). He is eBay's Senior Manager of Developer Relations. You can reach him at firstname.lastname@example.org.