0

I can download a Json array in Windows 8 with the following code:

aString = "http://website.com/image/image_manifest.json";

private async void GetJSON(string aString)
        {
            var client = new HttpClient();
            var lResponse = await client.GetStringAsync(aString);
}

This works 100%

I am attempting to do the same in Windows phone with this

        private void GetJSON(string aNASAURL)
        {
            WebClient webClient = new WebClient();
            webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClientHandler);
              webClient.DownloadStringAsync(new Uri(aString));
}
    private void webClientHandler(object sender, DownloadStringCompletedEventArgs e)
        {
            var lResponse = e.Result;
}

This does not work, I receive this exception:

An exception of type 'System.Reflection.TargetInvocationException' occurred in System.ni.dll but was not handled in user code

Going into the inner exception I see this:

InnerException {System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.

Full Exception Below.

EDIT: The HttpClient class is not available to windows phone. I chose WebClient as per the interwebs suggestion. Open to other options. The await method doesn't seem to work and WebClient must be called Async. I think that it may have something to do with my conversion of string to URI. Unfortunately the url can't yet be made public but here is a similar url structure as string.

Edited for clarity......

> -     e   {System.Net.DownloadStringCompletedEventArgs}   System.Net.DownloadStringCompletedEventArgs
+       base    {System.Net.DownloadStringCompletedEventArgs}   System.ComponentModel.AsyncCompletedEventArgs {System.Net.DownloadStringCompletedEventArgs}
-       Result  'e.Result' threw an exception of type 'System.Reflection.TargetInvocationException' string {System.Reflection.TargetInvocationException}
-       base    {System.Reflection.TargetInvocationException: An exception occurred during the operation, making the result invalid.  Check InnerException for exception details. ---> System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
   at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
   at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.<EndGetResponse>b__d(Object sendState)
   at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)
   --- End of inner exception stack trace ---
   at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
   at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
   at System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result)
   --- End of inner exception stack trace ---
   at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
   at System.Net.DownloadStringCompletedEventArgs.get_Result()} System.Exception {System.Reflection.TargetInvocationException}
+       Data    {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
        HelpLink    null    string
        HResult -2146232828 int
-       InnerException  {System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
   at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
   at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.<EndGetResponse>b__d(Object sendState)
   at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)
   --- End of inner exception stack trace ---
   at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
   at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
   at System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result)}   System.Exception {System.Net.WebException}
+       [System.Net.WebException]   {System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
   at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
   at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.<EndGetResponse>b__d(Object sendState)
   at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)
   --- End of inner exception stack trace ---
   at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
   at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)
   at System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result)}   System.Net.WebException
+       Data    {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
        HelpLink    null    string
        HResult -2146233079 int
-       InnerException  {System.Net.WebException: The remote server returned an error: NotFound.
   at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
   at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.<EndGetResponse>b__d(Object sendState)
   at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)}  System.Exception {System.Net.WebException}
+       [System.Net.WebException]   {System.Net.WebException: The remote server returned an error: NotFound.
   at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
   at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.<EndGetResponse>b__d(Object sendState)
   at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)}  System.Net.WebException
+       Data    {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
        HelpLink    null    string
        HResult -2146233079 int
+       InnerException  null    System.Exception
        Message "The remote server returned an error: NotFound."    string
        Source  "System.Windows"    string
        StackTrace  "   at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)\r\n   at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClasse.<EndGetResponse>b__d(Object sendState)\r\n   at System.Net.Browser.AsyncHelper.<>c__DisplayClass1.<BeginOnUI>b__0(Object sendState)"    string
+       Static members      
+       Non-Public members      
        Message "The remote server returned an error: NotFound."    string
        Source  "System.Windows"    string
        StackTrace  "   at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)\r\n   at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)\r\n   at System.Net.WebClient.GetWebResponse(WebRequest request, IAsyncResult result)\r\n   at System.Net.WebClient.DownloadBitsResponseCallback(IAsyncResult result)"  string
+       Static members      
+       Non-Public members      
        Message "An exception occurred during the operation, making the result invalid.  Check InnerException for exception details."   string
        Source  "System"    string
        StackTrace  "   at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()\r\n   at System.Net.DownloadStringCompletedEventArgs.get_Result()" string
+       Static members      
+       Non-Public members      
pnuts
  • 58,317
  • 11
  • 87
  • 139
Sean Dunford
  • 938
  • 1
  • 9
  • 24

2 Answers2

3

You should be using DownloadStringTaskAsync rather than DownloadStringAsync- at that point you'll be able to await the result, although only in an async method. EDIT: I thought that was available on WP8, but apparently it's not.

If you want to use HttpClient in a Windows Phone app, you can use the Microsoft.Net.Http NuGet package.

(You can use DownloadStringAsync, which is the "old" way of using WebClient, but then you need to subscribe to the appropriate events instead. Using async/await is much cleaner.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • My webclient doesn't have a method DownloadStringTaskAsync what are you calling that from? Edit: I misread what you said. Below stands true for DownloadStringAsync not DownloadStringTaskAsync I tried that. Though, it throws an error. It says I cannot await DownloadStringAsync because it is void. You cannot await void. >Error 1 Cannot await 'void' – Sean Dunford May 04 '13 at 08:03
  • 1
    @SeanDunford: I didn't say to await DownloadStringAsync - I said to await DownloadStringTaskAsync. They're different methods. – Jon Skeet May 04 '13 at 08:03
  • 1
    Hmmm... I thought WP8 *did* have DownloadStringTaskAsync. If it doesn't, I'd recommend the Microsoft.Net.Http client instead. – Jon Skeet May 04 '13 at 08:10
  • Error 1 'System.Net.WebClient' does not contain a definition for 'DownloadStringTaskAsync' and no extension method 'DownloadStringTaskAsync' accepting a first argument of type 'System.Net.WebClient' could be found (are you missing a using directive or an assembly reference?) Though, I do see this http://msdn.microsoft.com/en-us/library/hh194294.aspx it doesn't appear here – Sean Dunford May 04 '13 at 08:11
  • Yeah, my confusion came from the names being similar and the one you suggested not being present at all for my project type. I will take a look into the one you suggested. It just irks me that it's puking an exception. The code is "right" even if it's old so not sure why it isn't working. Which makes me fear that the problem is somewhere else. – Sean Dunford May 04 '13 at 08:12
  • Well that NuGet package does this Could not install package 'Microsoft.Net.Http 2.0.20710.0'. You are trying to install this package into a project that targets 'WindowsPhone,Version=v8.0', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author. – Sean Dunford May 04 '13 at 08:16
  • Dan Roth (the owner of the System.Net.Http Nuget package) responded via email: "System.Net.Http.dll is not support on XNA, Phone or Silverlight at this point. It is only support on .NET 4 (through ASP.NET Web API), .NET 4.5. and the .NETCore Profile in Windows 8." So that is the unfortunate answer to this question. http://stackoverflow.com/questions/12525168/cant-install-system-net-http-package-into-a-windows-phone-7-1-silverlight-proje – Sean Dunford May 04 '13 at 08:18
  • 1
    @Sean: I don't know whether I linked to the beta version or not, but that's what you want. I'm afraid I can't help any more for now - I'm out with the family. I'll look tonight if you haven't got any other answers. – Jon Skeet May 04 '13 at 08:21
  • The package specifically says it supports WP8. Make sure you're downloading the latest beta version and that you've got the latest version of nuget. I believe the answer you're referring to was before the extra package came out. – Jon Skeet May 04 '13 at 08:33
1

You can write a function similar to DownloadStringTaskAsync Jon Skeet suggested.

WebClient wc = new WebClient();
string result = await wc.DownloadAsync("http://www.stackoverflow.com");

public static partial class MyExtensions
{
    public static Task<string> DownloadAsync(this WebClient wc, string url)
    {
        TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
        DownloadStringCompletedEventHandler completed = null;

        completed = (s, e) =>
        {
            try
            {
                tcs.SetResult(e.Result);
            }
            catch (Exception ex)
            {
                tcs.SetException(ex.InnerException ?? ex);
            }
            finally
            {
                wc.DownloadStringCompleted -= completed;
            }
        };

        wc.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12";
        wc.DownloadStringCompleted += completed;
        wc.DownloadStringAsync(new Uri(url));

        return tcs.Task;
    }
}
I4V
  • 34,891
  • 6
  • 67
  • 79