0

I am super stuck on a simple api usage for over a week now. Here are the details.

Trying to make an api call to ebay.com. Here is what my code looks like...

This is the starting pages code:

 protected void Button1_Click(object sender, EventArgs e)
    {
        Response.Redirect("Results.aspx?Keywords=" + searchString.Text);  
    }

The page is directed to this bit of code:

if (Request.QueryString["Keywords"] != null){
        string keywords = Request.QueryString["Keywords"];
            string myAppID = "HIDDEN";
            var xml = XDocument.Load("http://svcs.ebay.com/services/search/FindingService/v1?OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.0.0&SECURITY-APPNAME=" + myAppID + "&RESPONSE-DATA-FORMAT=XML&REST-PAYLOAD&keywords=" + keywords + "&paginationInput.entriesPerPage=5");
            XNamespace ns = "http://www.ebay.com/marketplace/search/v1/services";
            var titles = from item in xml.Root.Descendants(ns + "title")
                              select new{
                                  title = xml.Descendants(ns + "title").Select (x => x.Value),
                              };
        foreach (var item in titles){
                Label1.Text += item;
            } 
        }

Here is the xml example:

<findItemsByKeywordsResponse xmlns="http://www.ebay.com/marketplace/search/v1/services">
<searchReslut count="5">
<item>
    <title></title>
</item>
<item>
    <title></title>
</item>
<item>
    <title></title>
</item>

I really rather turn the items into an array not just list them out. Just thought I would try the easier approach first. Error I get is: The for loop output to my label looks like this:

{ title = System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String] }{ title = System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String] }{ title = System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String] }{ title = System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String] }{ title = System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String] }

And the output exception is:

A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll An exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll but was not handled in user code The thread '' (0x27ee4) has exited with code 0 (0x0).

Any help is appreciated!

Cheran Shunmugavel
  • 8,319
  • 1
  • 33
  • 40
allencoded
  • 7,015
  • 17
  • 72
  • 126
  • 1
    You XML in the sample is way too big. I strongly recommend making it smaller (to about 7-10 lines) but still valid and reproducing the issue. I suspect you'll find where error comes from while doing so. If not - would be much easier to answer. – Alexei Levenkov Jun 27 '12 at 00:34
  • Edits made above thanks Alexei – allencoded Jun 27 '12 at 02:41

2 Answers2

1

The exception is coming from:

var titles = from item in xml.Root.Descendants(ns + "title")
             select new
             {
                 title = item.Parent.Element("title").Value,
             };

You don't need to go to the parent, you can just directly get the value of title since that is what you are searching for:

xml.Descendants(ns + "title").Select (x => x.Value)

Also, please take a look here Asking Better Questions, as it'll likely get you faster/better responses. There is a ton of code in your question that is not relevant, and is hard to parse to get to what you actually need help with.

Community
  • 1
  • 1
Ocelot20
  • 10,510
  • 11
  • 55
  • 96
  • But there are multiple titles...I will give your code a whirl and see if it works! – allencoded Jun 27 '12 at 01:49
  • The first part of the query (the `Descendants` part) selects all the title elements in the xml, and the select simply takes the value of each. It will get anything named "title" in the whole XDocument. If that's not what you're looking for, please update the question. – Ocelot20 Jun 27 '12 at 01:53
  • nope that did seem to work. but now I am getting this when i take that code through the for loop: title = System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String] – allencoded Jun 27 '12 at 01:55
  • That is because title is not yet known (deferred execution). Did you run it through and get an exception? – Ocelot20 Jun 27 '12 at 01:58
  • A first chance exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll An exception of type 'System.Threading.ThreadAbortException' occurred in mscorlib.dll but was not handled in user code – allencoded Jun 27 '12 at 02:04
  • Where are you hitting this exception? I have reduced your example down in LINQPad using the provided XML and it works fine. Either you'll have to reduce the example to the smallest reproducible steps, or nobody will be able to help. – Ocelot20 Jun 27 '12 at 02:08
  • I cleaned up the code above in my post. The only code that is not included above is the Respone.Redirect on another page, but this works fine. – allencoded Jun 27 '12 at 02:41
  • Glad you mentioned that...Response.Redirect works by throwing a ThreadAbortException. Your problem probably has nothing to do with this code at all. – Ocelot20 Jun 27 '12 at 02:43
  • http://stackoverflow.com/questions/2777105/response-redirect-causes-system-threading-threadabortexception Will help you. – Ocelot20 Jun 27 '12 at 02:44
  • hmmm thanks for the lead. I will look into that and edit the question again above – allencoded Jun 27 '12 at 02:57
  • weird thing is that it worked though when i only wanted the first value. curious why would it mess up when i want multiple values? – allencoded Jun 27 '12 at 03:13
0

This should be fairly simple to accomplish. Try using the code below. The top part I am just setting up your sample XML from your example and parsing it to a XElement (note: some closing tags were missing, also I am assuming the 'searchReslut' node is supposed to be 'searchResult'). Next, I am grabbing all of the descendant nodes from the root node that have a name of 'title' and where the value is not null. Then I am simply looping through the IEnumerable that is created, and concatenating the text of the label. Let me know if there are any questions.

string ns = "http://www.ebay.com/marketplace/search/v1/services";
string returnedXml = "<findItemsByKeywordsResponse xmlns=\"" + ns + "\">" +
                    "<searchReslut count=\"5\">" +
                        "<item>" +
                            "<title>Title1</title>" +
                        "</item>" +
                        "<item>" +
                            "<title>Title2</title>" +
                        "</item>" +
                        "<item>" +
                            "<title>Title3</title>" +
                        "</item>" +
                     "</searchReslut>" +
                    "</findItemsByKeywordsResponse>";
        XElement xml = XElement.Parse(returnedXml);
        IEnumerable<XElement> titleNodes = xml.Descendants("title").Where(x => x.Value != null);
        foreach (XElement t in titleNodes)
        {
            Label1.Text += t.Value;
        }            
Chris Knight
  • 1,448
  • 1
  • 15
  • 21