Retrieving a list of eBay categories using the .NET SDK and GetCategoriesCall

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 xmlns="urn:ebay:apis:eBLBaseComponents">
         <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: ,

Print | posted @ Monday, June 25, 2012 2:06 PM

Comments on this entry:

Gravatar # re: Retrieving a list of eBay categories using the .NET SDK and GetCategoriesCall
by Jigna at 12/21/2012 5:04 AM

Hi...thank you for such a nice article...
can anyone tell how can I add category or remove category created by me...

Thanks in advance..
Gravatar # re: Retrieving a list of eBay categories using the .NET SDK and GetCategoriesCall
by Bill at 12/21/2012 11:26 AM

The categories are set by eBay themselves, you can't add to them...
Gravatar # re: Retrieving a list of eBay categories using the .NET SDK and GetCategoriesCall
by Sudheep at 12/5/2013 11:52 PM

Hi,
Thank you very much.
"apiCall.DetailLevelList.Add(DetailLevelCodeType.ReturnAll); " was not mentioned in any doc I referred.
Gravatar # re: Retrieving a list of eBay categories using the .NET SDK and GetCategoriesCall
by Odelya at 2/20/2014 12:52 PM

Hi!
How can I obtain the app token?
I see only cerdId and appId in the Google developer web site
Post A Comment
Title:
Name:
Email:
Comment:
Verification: