2015-08-26 3 views
1

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

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

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

Спасибо.

ответ

0

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

+0

Нужно ли это в .NET 4.5? Я думал, что это требуется только для .NET 4 или ниже? – Thierry

+0

Это была проблема! Не понимаю, почему они не включаются автоматически, когда решение Silverlight или WP выбрано как часть платформы для поддержки! – Thierry

Смежные вопросы