首页 文章

HttpClient PostAsync()不起作用

提问于
浏览
1

在我的Xamarin Forms App中

我正在尝试将Json字符串发布到我的web服务,当我使用以下代码时,它是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] in:0 at System.Threading.Tasks.TaskFactory1 [TResult] .FromAsyncCoreLogic(System.IAsyncResult iar,System.Func2 [T,TResult] endFunction,System .Action1 [T] endAction,System.Threading.Tasks.Task1 [TResult] promise,System.Boolean requiresSynchronization)[0x00014] in:0 ---从抛出异常的上一个位置的堆栈跟踪结束---在System . Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()[0x0000c] in:0,System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task任务)[0x0004e] in:0,System.Runtime.CompilerServices.TaskAwaiter . HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task任务)[0x0002e] in:0,System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(System.Threading.Tasks.Task任务)[0x0000b] in:0,System.Runtime.CompilerServices . 在<a中配置了TaskAwaitable1 ConfiguredTaskAwaiter [TResult] .GetResult()[0x00000] 66f207c1e5949e9a252c01e27bbd34e>:0在System.Net.Http.HttpClientHandler <SendAsync> c__async0.MoveNext()[0x0041e] in <566d6cf6576345098cb5e08ad43d5e78>:0 ---从抛出异常的上一个位置开始的堆栈跟踪结束---在System.Runtime System.Runtime中的<a66f207c1e5949e9a252c01e27bbd34e>中的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System.Threading.Tasks.Task任务)[0x0004e]中的<a66f207c1e5949e9a252c01e27bbd34e>中的.ExceptionServices.ExceptionDispatchInfo.Throw()[0x0000c]:0 .CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task任务)[0x0002e]在<a66f207c1e5949e9a252c01e27bbd34e>:0中的System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(System.Threading.Tasks.Task任务)[0x0000b] in < a66f207c1e5949e9a252c01e27bbd34e>:0 at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1 ConfiguredTaskAwaiter [TResult] .GetResult()[0x00000] in:0 at System.Net.Http.HttpClient c__async0.MoveNext()[0x000f3] in <566d6cf6576345098cb5e08ad43d5e78>:0 ---从抛出异常的上一个位置开始的堆栈跟踪结束---在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess上的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()[0x0000c]中:0 (System.Threading.Tasks.Task任务)[0x0004e] in:0:System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task task)[0x0002e] in:0 at System.Runtime.CompilerServices.TaskAwaiter .ValidateEnd(System.Threading.Tasks.Task任务)[0x0000b] in:0 at System.Runtime.CompilerServices.TaskAwaiter`1 [TResult] .GetResult()[0x00000] in:0 at MyAPP.Webservice d _4.MoveNext() C:\ MyProject \ Classes \ Webservice.cs中的[0x000d0]:140}

还试过:SendAsync()TyM.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 回答

  • 1

    您可以使用 SendAsync()HttpCompletionOption.ResponseHeadersRead 而不是 PostAsync() ,问题在于读取响应,它在未准备就绪时正在读取 .

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

    使用 HttpCompletionOption.ResponseHeadersRead

    只要有响应并读取 Headers ,操作就应该完成 . 内容尚未阅读 .

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

    由于您使用的是 .Result.Waitawait ,因此最终会导致代码中出现 deadlock .

    您可以在 async 方法中使用 ConfigureAwait(false) preventing deadlock

    像这样:

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

    您可以尽可能使用ConfigureAwait(false)来阻止异步代码 .

相关问题