Ошибка HttpClient в файле PCL

Я только что создал проект PCL в VS 2013, добавил в свой проект следующие пакеты Nuget и выбрал все доступные платформы, так как хочу повторно использовать это в .NET и в своих проектах Xamarin.

  • Клиентские библиотеки Microsoft HTTP
  • Json.NET

Но в следующей строке:

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

Я получаю следующую ошибку:

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

и в этой строке:

return await response.Content.ReadAsStringAsync();

Я получаю следующую ошибку:

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

Это полный код, который отлично работает в общем проекте из моего универсального приложения.

    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();
    }

Это всего лишь несколько статей, которые я прочитал, но ни одна из них не указывает на правильное решение:

Мне удалось создать рабочую функцию, и она немного отличается от приведенной выше, но принцип остается прежним, но я не уверен, что это правильный способ сделать это, поскольку я делаю «ожидание» внутри функции. а не из приложения, которое его вызывает. Кто-то может просто захотеть подтвердить, что нижеприведенное также в порядке ?? Обратите внимание, что пока он компилируется, у меня еще не было возможности попробовать его в Xamarin.

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);
            }
        }
    }

Любые идеи, как я могу решить проблемы с моей первой функцией? Вторая функция в порядке?

Спасибо.


person Thierry    schedule 26.08.2015    source источник


Ответы (1)


Установите пакет NuGet Microsoft.Bcl.Async, чтобы иметь поддержку async и await.

person Wosi    schedule 26.08.2015
comment
Нужно ли мне это в .NET 4.5? Я думал, что это требуется только для .NET 4 или ниже? - person Thierry; 26.08.2015
comment
Это действительно была проблема все это время!! Не понимаю, почему они не включаются автоматически, когда в качестве части платформы для поддержки выбрано решение Silverlight или WP! - person Thierry; 29.08.2015