2016-12-22 5 views
1

В моей Xamarin Forms приложенияHttpClient PostAsync() не работает

Я пытаюсь разместить JSON строки в моем WebService Wich является RESTful API , когда я использую следующий код:

public static async Task<bool> SaveRolAsync(Methods Method, Role Rol) 
    { 
     try 
     { 
      HttpClient client = new HttpClient(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

      var uri = ("http://myservice.com/roles/"); 
      HttpResponseMessage response = null; 

      try 
      { 
       var jSettings = new JsonSerializerSettings(); 
       jSettings.NullValueHandling = NullValueHandling.Ignore; 
       jSettings.MissingMemberHandling = MissingMemberHandling.Ignore; 

       var JsonData = JsonConvert.SerializeObject(Rol); 
       var RoleContent = new StringContent(JsonData, Encoding.UTF8, "application/json"); 

       if (Method == Methods.PUT || Method == Methods.PATCH) 
       { 
        response = await client.PutAsync(uri, RoleContent); 
       } 

       if (Method == Methods.POST) 
       { 
        response = await client.PostAsync(uri, RoleContent); 
       } 

       if (Method == Methods.DELETE) 
       { 
        throw new NotImplementedException(); 
       } 

       return response.IsSuccessStatusCode; 

      } 
      catch (JsonException jse) 
      { 
       return false; 
      } 
     } 
     catch (Exception ex) 
     { 
      // Exceptions Throws here 
      // @T This line i got The request requires buffering data to succeed 
      return false; 
     } 
    } 

Исключение бросков:

запрос требует буферизации данных для достижения успеха

Трассировка стека:

{System.Net.WebException: запрос требует буферизации данных в преуспевать. на System.Net.HttpWebRequest.EndGetResponse (System.IAsyncResult AsyncResult) [0x00064] в : 0 в System.Threading.Tasks.TaskFactory 1[TResult].FromAsyncCoreLogic (System.IAsyncResult iar, System.Func 2 [Т, TResult] EndFunction, System.Action 1[T] endAction, System.Threading.Tasks.Task 1 [TResult] обещание, System.Boolean требует синхронизацию) [0x00014] в : 0 --- Конец трассировки стека из предыдущего места, в котором исключение было сброшено --- на System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] в : 0 на System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Задача System.Threading.Tasks.Task) [0x0004e] в : 0 на System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task задача) [0x0002e] в : 0 в System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (задача System.Threading.Tasks.Task) [0x0000b] в : 0 в System.Runtime.CompilerServices.ConfiguredTaskAwaitable 1+ConfiguredTaskAwaiter[TResult].GetResult () [0x00000] in <a66f207c1e5949e9a252c01e27bbd34e>:0 at System.Net.Http.HttpClientHandler+<SendAsync>c__async0.MoveNext() [0x0041e] in <566d6cf6576345098cb5e08ad43d5e78>:0 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] in <a66f207c1e5949e9a252c01e27bbd34e>:0 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0004e] in <a66f207c1e5949e9a252c01e27bbd34e>:0 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in <a66f207c1e5949e9a252c01e27bbd34e>:0 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in <a66f207c1e5949e9a252c01e27bbd34e>:0 at System.Runtime.CompilerServices.ConfiguredTaskAwaitable 1 + ConfiguredTaskAwaiter [TResult] .GetResult () [0x00000] в: 0 в System.Net.Http.HttpClient + c__async0.MoveNext() [0x000f3] в < 566d6cf6576345098cb5e08ad43d5e78>: 0 --- Конец трассировки стека из предыдущего места, где исключение было выбрано --- System.Runtime.ExceptionServices.ExceptionDisp atchInfo.Throw() [0x0000c] в: 0 в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task задача) [0x0004e] в : 0 в System.Runtime.CompilerServices.TaskAwaiter .HandleNonSuccessAndDebuggerNotification (задача System.Threading.Tasks.Task) [0x0002e] в : 0 в System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task задача) [0x0000b] в : 0 в System.Runtime.CompilerServices.TaskAwaiter`1 [TResult] .GetResult() [0x00000] в: 0 в MyAPP.Webservice + d__4.MoveNext() [0x000d0] в C: \ MyProject \ Cla sses \ Webservice.cs: 140}

** Также пробовал: SendAsync() Ty M.Wiśnicki **

public static async Task<bool> SaveRolAsync(MediwareLib.Methods Method, Role Rol) 
    { 
     try 
     { 
      HttpClient client = new HttpClient(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

      var uri = (BaseRequestUrl + "roles/"); 
      HttpResponseMessage response = null; 
      var request = new HttpRequestMessage(); 

      try 
      { 
       var jSettings = new JsonSerializerSettings(); 
       jSettings.NullValueHandling = NullValueHandling.Ignore; 
       jSettings.MissingMemberHandling = MissingMemberHandling.Ignore; 

       var JsonData = JsonConvert.SerializeObject(Rol); 

       var RoleContent = new StringContent(JsonData, Encoding.UTF8, "application/json"); 

       if (Method == MediwareLib.Methods.PUT || Method == MediwareLib.Methods.PATCH) 
       { 
        request = new HttpRequestMessage(HttpMethod.Put, uri); 
        request.Content = RoleContent; 

        response = await client.SendAsync(request, 
        HttpCompletionOption.ResponseHeadersRead); 
       } 

       if (Method == MediwareLib.Methods.POST) 
       { 
        request = new HttpRequestMessage(HttpMethod.Post, uri); 
        request.Content = RoleContent; 

        response = await client.SendAsync(request, 
        HttpCompletionOption.ResponseHeadersRead); 
       } 

       if (Method == MediwareLib.Methods.DELETE) 
       { 
        throw new NotImplementedException(); 
        // response = await client.DeleteAsync(uri + Rol.Id); 
       } 

       return response.IsSuccessStatusCode; 

      } 
      catch (JsonException jse) 
      { 
       Globals.Log("SaveRolAsync: " + jse.ToString()); 
       return false; 
      } 
     } 
     catch (Exception ex) 
     { 
      Globals.Log("SaveRolAsync: " + ex.ToString()); 
      return false; 
     } 

    } 

enter image description here

+2

Так что же вы показали свое исследование? Вы читали [Запрос требует буферизации данных для успеха HttpClient] (http://stackoverflow.com/questions/40368724/the-request-requires-buffering-data-to-succeed-httpclient) и [Запрос главы с HttpClient] (http://stackoverflow.com/questions/25509233/head-request-with-httpclient)? Вы заметили, что вы отправляете PUT даже «if (Method == Methods.POST)»? Отвечает ли ваш сервис перенаправлением? – CodeCaster

+0

Ofc я прочитал другие сообщения stackoverflow, но я хочу отправить строку json, а не запрос Google. –

+0

HTTP-запрос - это HTTP-запрос, содержащий ли он результаты поиска или данные JSON. – CodeCaster

ответ

1

Вы можете использовать SendAsync() с HttpCompletionOption.ResponseHeadersRead вместо PostAsync(), проблема с ответом чтения, это чтение, когда он не готов.

var request = new HttpMessageRequest(yourUrl); 
request.Content = yourContent; 
var response = await client.SendAsync(request, 
HttpCompletionOption.ResponseHeadersRead); 

Использование HttpCompletionOption.ResponseHeadersRead

операция должна завершить как ответ доступен и заголовки читаются. Содержимое пока не читается.

Edit Вы можете использовать HttpWebRequest вместо HttpClient

public async Task<string> PostTest(object sampleData, string uri) 
    { 
     var request = (HttpWebRequest) WebRequest.Create(new Uri(uri)); 
     request.ContentType = "application/json"; 
     request.Method = "POST"; 
     request.Timeout = 4000; //ms 
     var itemToSend = JsonConvert.SerializeObject(sampleData); 
     using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync())) 
     { 
      streamWriter.Write(itemToSend); 
      streamWriter.Flush(); 
      streamWriter.Dispose(); 
     } 

     // Send the request to the server and wait for the response: 
     using (var response = await request.GetResponseAsync()) 
     { 
      // Get a stream representation of the HTTP web response: 
      using (var stream = response.GetResponseStream()) 
      { 
       var reader = new StreamReader(stream); 
       var message = reader.ReadToEnd(); 
       return message; 
      } 
     } 
    } 
+0

Такая же ошибка :(System.Net.WebException: запрос требует буферизации данных для успеха. –

+0

@StefanvandeLaarschot Вы используете 'new HttpRequestMessage (HttpMethod.Post , uri); 'но я написал без' HttpMethod', используйте только с uri. –

+0

Он не может ожидать HttpMethod, uri или String как Uri –

1

Поскольку вы используете .Result или .Wait или await это будет в конечном итоге вызывает тупик в вашем коде.

вы можете использовать ConfigureAwait(false) в async методов для предотвращения ТУПИК

так:

response = await client.PostAsync(uri, RoleContent).ConfigureAwait(false); 

вы можете использовать ConfigureAwait(false) везде, где возможно, чтобы не закрыть асинхронным кодекса.