Retrieving a list of eBay categories using the .NET SDK and GetCategoriesCall
- by Bill Osuch
eBay offers a .Net SDK for its Trading API - this post will show you the basics of making an API call and retrieving a list of current categories. You'll need the category ID(s) for any apps that post or search eBay. To start, download the latest SDK from https://www.x.com/developers/ebay/documentation-tools/sdks/dotnet and create a new console app project. Add a reference to the eBay.Service DLL, and a few using statements: using eBay.Service.Call; using eBay.Service.Core.Sdk; using eBay.Service.Core.Soap; I'm assuming at this point you've already joined the eBay Developer Network and gotten your app IDs and user tokens. If not: Join the developer program Generate tokens Next, add an app.config file that looks like this: <?xml version="1.0"?> <configuration> <appSettings> <add key="Environment.ApiServerUrl" value="https://api.ebay.com/wsapi"/> <add key="UserAccount.ApiToken" value="YourBigLongToken"/> </appSettings> </configuration> And then add the code to get the xml list of categories: ApiContext apiContext = GetApiContext(); GetCategoriesCall apiCall = new GetCategoriesCall(apiContext); apiCall.CategorySiteID = "0"; //Leave this commented out to retrieve all category levels (all the way down): //apiCall.LevelLimit = 4; //Uncomment this to begin at a specific parent category: //StringCollection parentCategories = new StringCollection(); //parentCategories.Add("63"); //apiCall.CategoryParent = parentCategories; apiCall.DetailLevelList.Add(DetailLevelCodeType.ReturnAll); CategoryTypeCollection cats = apiCall.GetCategories(); using (StreamWriter outfile = new StreamWriter(@"C:\Temp\EbayCategories.xml")) { outfile.Write(apiCall.SoapResponse); } GetApiContext() (provided in the sample apps in the SDK) is required for any call: static ApiContext GetApiContext() { //apiContext is a singleton, //to avoid duplicate configuration reading if (apiContext != null) { return apiContext; } else { apiContext = new ApiContext(); //set Api Server Url apiContext.SoapApiServerUrl = ConfigurationManager.AppSettings["Environment.ApiServerUrl"]; //set Api Token to access eBay Api Server ApiCredential apiCredential = new ApiCredential(); apiCredential.eBayToken = ConfigurationManager.AppSettings["UserAccount.ApiToken"]; apiContext.ApiCredential = apiCredential; //set eBay Site target to US apiContext.Site = SiteCodeType.US; return apiContext; } } Running this will give you a large (4 or 5 megs) XML file that looks something like this: <soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <GetCategoriesResponse > <Timestamp>2012-06-06T16:03:46.158Z</Timestamp> <Ack>Success</Ack> <CorrelationID>d02dd9e3-295a-4268-9ea5-554eeb2e0e18</CorrelationID> <Version>775</Version> <Build>E775_CORE_BUNDLED_14891042_R1</Build> - <CategoryArray> <Category> <BestOfferEnabled>true</BestOfferEnabled> <AutoPayEnabled>true</AutoPayEnabled> <CategoryID>20081</CategoryID> <CategoryLevel>1</CategoryLevel> <CategoryName>Antiques</CategoryName> <CategoryParentID>20081</CategoryParentID> </Category> <Category> <BestOfferEnabled>true</BestOfferEnabled> <AutoPayEnabled>true</AutoPayEnabled> <CategoryID>37903</CategoryID> <CategoryLevel>2</CategoryLevel> <CategoryName>Antiquities</CategoryName> <CategoryParentID>20081</CategoryParentID> </Category> (etc.) You could work with this, but I wanted a nicely nested view, like this: <CategoryArray> <Category Name='Antiques' ID='20081' Level='1'> <Category Name='Antiquities' ID='37903' Level='2'/> </CategoryArray> ...so I transformed the xml: private void TransformXML(CategoryTypeCollection cats) { XmlElement topLevelElement = null; XmlElement childLevelElement = null; XmlNode parentNode = null; string categoryString = ""; XmlDocument returnDoc = new XmlDocument(); XmlElement root = returnDoc.CreateElement("CategoryArray"); returnDoc.AppendChild(root); XmlNode rootNode = returnDoc.SelectSingleNode("/CategoryArray"); //Loop through CategoryTypeCollection foreach (CategoryType category in cats) { if (category.CategoryLevel == 1) { //Top-level category, so we know we can just add it topLevelElement = returnDoc.CreateElement("Category"); topLevelElement.SetAttribute("Name", category.CategoryName); topLevelElement.SetAttribute("ID", category.CategoryID); rootNode.AppendChild(topLevelElement); } else { // Level number will determine how many Category nodes we are deep categoryString = ""; for (int x = 1; x < category.CategoryLevel; x++) { categoryString += "/Category"; } parentNode = returnDoc.SelectSingleNode("/CategoryArray" + categoryString + "[@ID='" + category.CategoryParentID[0] + "']"); childLevelElement = returnDoc.CreateElement("Category"); childLevelElement.SetAttribute("Name", category.CategoryName); childLevelElement.SetAttribute("ID", category.CategoryID); parentNode.AppendChild(childLevelElement); } } returnDoc.Save(@"C:\Temp\EbayCategories-Modified.xml"); } Yes, there are probably much cleaner ways of dealing with it, but I'm not an xml expert… Keep in mind, eBay categories do not change on a regular basis, so you should be able to cache this data (either in a file or database) for some time. The xml returns a CategoryVersion node that you can use to determine if the category list has changed. Technorati Tags: Csharp, eBay