0

Trying to get Google Suggestion. Im getting the XML back but when parsing using XDocument Im getting the following exception: "Data at the root level is invalid.". I cannot figure out what is causing it.

private const string _suggestSearchUrl = "http://www.google.com/complete/search?output=toolbar&q={0}&hl=en";

    public List<GoogleSuggestion> GetData(string query)
    {
        if (String.IsNullOrWhiteSpace(query))
        {
            throw new ArgumentException("Argument cannot be null or empty!", "query");
        }

        string result = String.Empty;

        using (HttpClient client = new HttpClient())
        {
            result = String.Format(_suggestSearchUrl, query);
        }


        XDocument doc = XDocument.Parse(result);  (I`m getting exception here)





        var suggestions = from suggestion in doc.Descendants("CompleteSuggestion")
                          select new GoogleSuggestion
                          {
                              Phrase = suggestion.Element("suggestion").Attribute("data").Value
                          };

        return suggestions.ToList();
Thomas
  • 67
  • 1
  • 11

1 Answers1

1

You're trying to parse your Uri, not making a request and parsing the response.

var response = await client.GetAsync(uri);
var result = await response.Content.ReadAsStringAsync();

You should also reuse your HttpClient instances, even though it's disposable.

George Helyar
  • 2,496
  • 16
  • 17
  • I`m having trouble when invoking the method, currently I`m passing my query string and waiting for the method to complete but it gangs there forever : Task> task = GetDataAsync("test"); task.Wait(); var x = task.Result; – Thomas Jun 10 '18 at 11:59
  • Ok it works I have found this thread: https://stackoverflow.com/questions/28601678/calling-async-method-on-button-click – Thomas Jun 10 '18 at 12:07
  • 1
    Make your method `async Task>`, rename to end with `Async` by convention so that the caller know to await it, and `await` it in the caller. You might also want to use `ConfigureAwait(false)` everywhere you use `await`, unless you are sure you want it to be `true`, which is the default but almost never what you want. Async is powerful but has a lot of caveats that make it harder than it should be. Try to avoid `.Result` and `.Wait()` – George Helyar Jun 10 '18 at 13:46