我如何能使一个HTTP POST请求和发送数据的主体?


当前回答

c# . net

    using System.Net.Http;
    
    private static readonly HttpClient httpClient = new HttpClient();

//POST    
    var values = new Object();
    values[0] = "Value1";
    values[2] = "Value2";
    values[n] = "ValueN";

    var content = new FormUrlEncodedContent(values);
    var response = await httpClient.PostAsync("URL", content);
    var responseString = await response.Content.ReadAsStringAsync();

    

//GET
 var response = await httpClient.GetStringAsync("URL");

其他回答

c# . net

    using System.Net.Http;
    
    private static readonly HttpClient httpClient = new HttpClient();

//POST    
    var values = new Object();
    values[0] = "Value1";
    values[2] = "Value2";
    values[n] = "ValueN";

    var content = new FormUrlEncodedContent(values);
    var response = await httpClient.PostAsync("URL", content);
    var responseString = await response.Content.ReadAsStringAsync();

    

//GET
 var response = await httpClient.GetStringAsync("URL");

这里有一些非常好的答案。让我发布一种不同的方法来设置你的头部与WebClient()。我还将向您展示如何设置API键。

        var client = new WebClient();
        string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + passWord));
        client.Headers[HttpRequestHeader.Authorization] = $"Basic {credentials}";
        //If you have your data stored in an object serialize it into json to pass to the webclient with Newtonsoft's JsonConvert
        var encodedJson = JsonConvert.SerializeObject(newAccount);

        client.Headers.Add($"x-api-key:{ApiKey}");
        client.Headers.Add("Content-Type:application/json");
        try
        {
            var response = client.UploadString($"{apiurl}", encodedJson);
            //if you have a model to deserialize the json into Newtonsoft will help bind the data to the model, this is an extremely useful trick for GET calls when you have a lot of data, you can strongly type a model and dump it into an instance of that class.
            Response response1 = JsonConvert.DeserializeObject<Response>(response);

如果你喜欢一个流畅的API,你可以使用Tiny.RestClient。在NuGet上可以买到。

var client = new TinyRestClient(new HttpClient(), "http://MyAPI.com/api");
// POST
var city = new City() { Name = "Paris", Country = "France" };
// With content
var response = await client.PostRequest("City", city)
                           .ExecuteAsync<bool>();

这个解决方案只使用标准的. net调用。

测试:

在企业WPF应用程序中使用。使用async/await来避免阻塞UI。 兼容。net 4.5+。 在没有参数的情况下进行测试(在幕后需要一个“GET”)。 使用参数进行测试(需要幕后的“POST”)。 使用标准的网页(如谷歌)进行测试。 使用内部基于java的web服务进行测试。

参考:

// Add a Reference to the assembly System.Web

代码:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;

private async Task<WebResponse> CallUri(string url, TimeSpan timeout)
{
    var uri = new Uri(url);
    NameValueCollection rawParameters = HttpUtility.ParseQueryString(uri.Query);
    var parameters = new Dictionary<string, string>();
    foreach (string p in rawParameters.Keys)
    {
        parameters[p] = rawParameters[p];
    }

    var client = new HttpClient { Timeout = timeout };
    HttpResponseMessage response;
    if (parameters.Count == 0)
    {
        response = await client.GetAsync(url);
    }
    else
    {
        var content = new FormUrlEncodedContent(parameters);
        string urlMinusParameters = uri.OriginalString.Split('?')[0]; // Parameters always follow the '?' symbol.
        response = await client.PostAsync(urlMinusParameters, content);
    }
    var responseString = await response.Content.ReadAsStringAsync();

    return new WebResponse(response.StatusCode, responseString);
}

private class WebResponse
{
    public WebResponse(HttpStatusCode httpStatusCode, string response)
    {
        this.HttpStatusCode = httpStatusCode;
        this.Response = response;
    }
    public HttpStatusCode HttpStatusCode { get; }
    public string Response { get; }
}

不带参数调用(在幕后使用“GET”):

 var timeout = TimeSpan.FromSeconds(300);
 WebResponse response = await this.CallUri("http://www.google.com/", timeout);
 if (response.HttpStatusCode == HttpStatusCode.OK)
 {
     Console.Write(response.Response); // Print HTML.
 }

使用参数调用(在幕后使用“POST”):

 var timeout = TimeSpan.FromSeconds(300);
 WebResponse response = await this.CallUri("http://example.com/path/to/page?name=ferret&color=purple", timeout);
 if (response.HttpStatusCode == HttpStatusCode.OK)
 {
     Console.Write(response.Response); // Print HTML.
 }

为什么这不是完全无关紧要的?执行请求并不是处理结果。而且似乎还涉及到一些。net Bug——参见HttpClient中的Bug。GetAsync应该抛出WebException,而不是TaskCanceledException

我最终得到了这样的代码:

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

    // https://devblogs.microsoft.com/dotnet/net-5-new-networking-improvements/
    } catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) {
        return (false, ex.ToString(), null, WebExceptionStatus.Timeout);

    } catch (TaskCanceledException ex) {
        return (false, ex.ToString(), null, WebExceptionStatus.RequestCanceled);

    } catch (Exception ex) {
        return (false, WebExceptionStatus.UnknownError, null, ex.ToString());
    }
}

这将根据postBuffer是否为空来执行GET或POST操作。

如果Success为true,响应将在ResponseAsString中。

如果Success为false,你可以检查WebExceptionStatus, HttpStatusCode和ResponseAsString,看看哪里出了问题。