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: Csharp, eBay