How to make an HTTP POST web request

后端 未结 14 3372
有刺的猬
有刺的猬 2020-11-21 04:31

Canonical
How can I make an HTTP request and send some data using the POST method?

14条回答
  •  生来不讨喜
    2020-11-21 05:08

    Why is this not totally trivial? Doing the request is not and especially not dealing with the results and seems like there are some .NET bugs involved as well - see Bug in HttpClient.GetAsync should throw WebException, not TaskCanceledException

    I ended up with this code:

    static async Task<(bool Success, WebExceptionStatus WebExceptionStatus, HttpStatusCode? HttpStatusCode, string ResponseAsString)> HttpRequestAsync(HttpClient httpClient, string url, string postBuffer = null, CancellationTokenSource cts = null) {
        try {
            HttpResponseMessage resp = null;
    
            if (postBuffer is null) {
                resp = cts is null ? await httpClient.GetAsync(url) : await httpClient.GetAsync(url, cts.Token);
    
            } else {
                using (var httpContent = new StringContent(postBuffer)) {
                    resp = cts is null ? await httpClient.PostAsync(url, httpContent) : await httpClient.PostAsync(url, httpContent, cts.Token);
                }
            }
    
            var respString = await resp.Content.ReadAsStringAsync();
            return (resp.IsSuccessStatusCode, WebExceptionStatus.Success, resp.StatusCode, respString);
    
        } catch (WebException ex) {
            WebExceptionStatus status = ex.Status;
            if (status == WebExceptionStatus.ProtocolError) {
                // Get HttpWebResponse so that you can check the HTTP status code.
                using (HttpWebResponse httpResponse = (HttpWebResponse)ex.Response) {
                    return (false, status, httpResponse.StatusCode, httpResponse.StatusDescription);
                }
            } else {
                return (false, status, null, ex.ToString()); 
            }
    
        } catch (TaskCanceledException ex) {
            if (cts is object && ex.CancellationToken == cts.Token) {
                // a real cancellation, triggered by the caller
                return (false, WebExceptionStatus.RequestCanceled, null, ex.ToString());
            } else {
                // a web request timeout (possibly other things!?)
                return (false, WebExceptionStatus.Timeout, null, ex.ToString());
            }
    
        } catch (Exception ex) {
            return (false, WebExceptionStatus.UnknownError, null, ex.ToString());
        }
    }
    

    This will do a GET or POST depends if postBuffer is null or not

    if Success is true the response will then be in ResponseAsString

    if Success is false you can check WebExceptionStatus, HttpStatusCode and ResponseAsString to try to see what went wrong.

提交回复
热议问题