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