1

I've just created a PCL project in VS 2013 and added the following Nuget packages to my project and selected all available platforms as I want to re-use this in .NET and in my Xamarin projects.

  • Microsoft HTTP Client Libraries
  • Json.NET

But on the following line:

HttpResponseMessage response = await client.PostAsync(uri, content);

I'm getting the following error:

Cannot await 
'System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>'

and on this line:

return await response.Content.ReadAsStringAsync();

I'm getting the following error:

Cannot await 'System.Threading.Tasks.Task<string>'

This is the full code which works fine in the shared project from my Universal app.

    public static async Task<string> PostDataAsync<T>(string uriString, 
    T data, ContentType contentType, bool isWrapped)
    {
        HttpClient client = new HttpClient();

        Uri uri = new Uri(uriString);

        string wrappedName = data.GetType().Name;
        string postData = string.Empty;
        string prefix = string.Empty;
        string suffix = string.Empty;

        if (contentType == ContentType.Xml)
        {
            //postData = SerializerHelper.SerializeObjectToXML<T>(data, 
            //true, true, true, false);
        }
        else
        {
            if (isWrapped)
            {
                prefix = string.Concat("{\"", data.GetType().Name, "\":");
                suffix = "}";
            }
            postData = prefix + JsonConvert.SerializeObject(data) + suffix;
        }

        client.DefaultRequestHeaders.Accept.Add(new 
        MediaTypeWithQualityHeaderValue(contentType == 
        ContentType.Json ? "application/json" : "application/xml"));

       client.DefaultRequestHeaders.Host = uri.Host;

        StringContent content = new StringContent(postData,
        System.Text.Encoding.UTF8, contentType ==
        ContentType.Json ? "application/json" : "application/xml");

        HttpResponseMessage response = await client.PostAsync(uri, content);

        if (response.StatusCode == HttpStatusCode.NotFound)
            throw new NetworkConnectivityException();
        else if (response.StatusCode != HttpStatusCode.OK)
            throw new Exception(response.RequestMessage.ToString());

        return await response.Content.ReadAsStringAsync();
    }

These are just a few of the articles I've read but none are pointing to the right solution:

I've managed to create a working function and differs slightly from the one above, but the principle remains the same but I'm not sure this is the right way to go about it as I'm doing the "waiting" within the function rather than from the app that's calling it. Someone might just want to confirm if the below is also ok?? Note that while it compiles, I haven't had a chance to try in Xamarin yet.

public static Task<U> PostDataAsync<T, U>(string baseAddress, string
requestUri, T data, ContentType contentType = ContentType.Json, 
bool isWrapped = true, double timeOut = 1200000)
    {
        string contentTypeString = (contentType ==
        ContentType.Json ? "json" : "xml");

        using (HttpClientHandler handler = new HttpClientHandler())
        {
            using (HttpClient client = new HttpClient(handler))
            {
                client.BaseAddress = new Uri(baseAddress);
                client.Timeout = TimeSpan.FromMilliseconds(timeOut);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(
                    new MediaTypeWithQualityHeaderValue("application/" + 
                    contentTypeString));

                string postData = string.Empty;
                string prefix = string.Empty;
                string suffix = string.Empty;

                if (contentType == ContentType.Json)
                {
                    if (isWrapped)
                    {
                        prefix = string.Concat("{\"", 
                        data.GetType().Name, "\":");
                        suffix = "}";
                    }
                    postData = prefix + JsonConvert.
                    SerializeObject(data) + suffix;
                }
                else
                {

                }

                HttpRequestMessage request = new 
                HttpRequestMessage(HttpMethod.Post, requestUri);
                request.Content = new StringContent(postData,
                                                    Encoding.UTF8,
                                                    "application/" +
                contentTypeString);

                if (handler.SupportsTransferEncodingChunked())
                {
                    request.Headers.TransferEncodingChunked = true;
                }

                HttpResponseMessage response = null;
                string dataReturned = string.Empty;
                U dataObject = default(U);

                Task resp = client.SendAsync(request)
                      .ContinueWith(responseTask =>
                      {
                          response = responseTask.Result;
                          if (responseTask.Result.IsSuccessStatusCode)
                          {
                              Task<string> dataTask = 
                              response.Content.ReadAsStringAsync();

                              dataReturned = dataTask.Result.ToString();
                              dataObject = JsonConvert.
                              DeserializeObject<U>(FixJson
                               (dataReturned, "Result"));
                          }
                          else
                          {
                              dataReturned = "HTTP Status: " +
                              response.StatusCode.ToString() + 
                              " - Reason: " + response.ReasonPhrase;
                          }
                      });

                resp.Wait();

                return Task.Factory.StartNew(() => dataObject);
            }
        }
    }

Any ideas how I can resolve the problems with my first function? Is the second function ok?

Thanks.

Community
  • 1
  • 1
Thierry
  • 6,142
  • 13
  • 66
  • 117

1 Answers1

0

Install the NuGet package Microsoft.Bcl.Async in order to have support for async and await.

Wosi
  • 41,986
  • 17
  • 75
  • 82
  • Do I still need this in .NET 4.5? I thought this was only required for .NET 4 or below? – Thierry Aug 26 '15 at 14:53
  • This was indeed the problem all along!! Don't understand why they don't included automatically when the solution has Silverlight or WP selected as part of platform to support! – Thierry Aug 29 '15 at 02:19