How to make HTTP POST web request
canonical:我如何使用
有几种方法可以执行http
方法A:httpclient
在.NET Framework 4.5+、.NET Standard 1.1+、.NET Core 1.0中提供+
目前首选的方法。异步的。其他平台的便携式版本可通过Nuget获得。
1 | using System.Net.Http; |
安装程序
建议为应用程序的生命周期实例化一个
1 |
柱
1 2 3 4 5 6 7 8 9 10 11 |
得到
1 | var responseString = await client.GetStringAsync("http://www.example.com/recepticle.aspx"); |
方法B:第三方图书馆
赖斯塔尔
尝试并测试了与RESTAPI交互的库。便携式。通过Nuget提供。
Flurl
更新的库拥有流畅的API和测试助手。引擎盖下的HTTPClient。便携式。通过Nuget提供。
1 | using Flurl.Http; |
柱
1 2 3 | var responseString = await"http://www.example.com/recepticle.aspx" .PostUrlEncodedAsync(new { thing1 ="hello", thing2 ="world" }) .ReceiveString(); |
得到
1 2 | var responseString = await"http://www.example.com/recepticle.aspx" .GetStringAsync(); |
方法C:传统
可用于:.NET Framework 1.1+、.NET Standard 2.0+、.NET Core 1.0+
1 2 3 | using System.Net; using System.Text; // for class Encoding using System.IO; // for StreamReader |
柱
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx"); var postData ="thing1=hello"; postData +="&thing2=world"; var data = Encoding.ASCII.GetBytes(postData); request.Method ="POST"; request.ContentType ="application/x-www-form-urlencoded"; request.ContentLength = data.Length; using (var stream = request.GetRequestStream()) { stream.Write(data, 0, data.Length); } var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); |
得到
1 2 3 4 5 | var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx"); var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); |
方法D:WebClient(现在也是传统方法)
可用于:.NET Framework 1.1+、.NET Standard 2.0+、.NET Core 2.0+
1 2 | using System.Net; using System.Collections.Specialized; |
柱
1 2 3 4 5 6 7 8 9 10 |
得到
1 2 3 4 | using (var client = new WebClient()) { var responseString = client.DownloadString("http://www.example.com/recepticle.aspx"); } |
简单获取请求
1 2 3 4 5 6 7 8 |
简单的POST请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | using System.Net; using System.Collections.Specialized; ... using (var wb = new WebClient()) { var data = new NameValueCollection(); data["username"] ="myUser"; data["password"] ="myPassword"; var response = wb.UploadValues(url,"POST", data); string responseInString = Encoding.UTF8.GetString(response); } |
msdn有一个样本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | using System; using System.IO; using System.Net; using System.Text; namespace Examples.System.Net { public class WebRequestPostExample { public static void Main() { // Create a request using a URL that can receive a post. WebRequest request = WebRequest.Create("http://www.contoso.com/PostAccepter.aspx"); // Set the Method property of the request to POST. request.Method ="POST"; // Create POST data and convert it to a byte array. string postData ="This is a test that posts this string to a Web server."; byte[] byteArray = Encoding.UTF8.GetBytes(postData); // Set the ContentType property of the WebRequest. request.ContentType ="application/x-www-form-urlencoded"; // Set the ContentLength property of the WebRequest. request.ContentLength = byteArray.Length; // Get the request stream. Stream dataStream = request.GetRequestStream(); // Write the data to the request stream. dataStream.Write(byteArray, 0, byteArray.Length); // Close the Stream object. dataStream.Close(); // Get the response. WebResponse response = request.GetResponse(); // Display the status. Console.WriteLine(((HttpWebResponse)response).StatusDescription); // Get the stream containing content returned by the server. dataStream = response.GetResponseStream(); // Open the stream using a StreamReader for easy access. StreamReader reader = new StreamReader(dataStream); // Read the content. string responseFromServer = reader.ReadToEnd(); // Display the content. Console.WriteLine(responseFromServer); // Clean up the streams. reader.Close(); dataStream.Close(); response.Close(); } } } |
这是以JSON格式发送/接收数据的完整工作示例,我使用了VS2013 Express版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | using System; using System.Collections.Generic; using System.Data; using System.Data.OleDb; using System.IO; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Web.Script.Serialization; namespace ConsoleApplication1 { class Customer { public string Name { get; set; } public string Address { get; set; } public string Phone { get; set; } } public class Program { private static readonly HttpClient _Client = new HttpClient(); private static JavaScriptSerializer _Serializer = new JavaScriptSerializer(); static void Main(string[] args) { Run().Wait(); } static async Task Run() { string url ="http://www.example.com/api/Customer"; Customer cust = new Customer() { Name ="Example Customer", Address ="Some example address", Phone ="Some phone number" }; var json = _Serializer.Serialize(cust); var response = await Request(HttpMethod.Post, url, json, new Dictionary<string, string>()); string responseText = await response.Content.ReadAsStringAsync(); List<YourCustomClassModel> serializedResult = _Serializer.Deserialize<List<YourCustomClassModel>>(responseText); Console.WriteLine(responseText); Console.ReadLine(); } /// <summary> /// Makes an async HTTP Request /// </summary> /// <param name="pMethod">Those methods you know: GET, POST, HEAD, etc...</param> /// <param name="pUrl">Very predictable...</param> /// <param name="pJsonContent">String data to POST on the server</param> /// <param name="pHeaders">If you use some kind of Authorization you should use this</param> /// <returns></returns> static async Task<HttpResponseMessage> Request(HttpMethod pMethod, string pUrl, string pJsonContent, Dictionary<string, string> pHeaders) { var httpRequestMessage = new HttpRequestMessage(); httpRequestMessage.Method = pMethod; httpRequestMessage.RequestUri = new Uri(pUrl); foreach (var head in pHeaders) { httpRequestMessage.Headers.Add(head.Key, head.Value); } switch (pMethod.Method) { case"POST": HttpContent httpContent = new StringContent(pJsonContent, Encoding.UTF8,"application/json"); httpRequestMessage.Content = httpContent; break; } return await _Client.SendAsync(httpRequestMessage); } } } |
这里有一些很好的答案。让我用一种不同的方法来设置WebClient()的头部。我还将向您演示如何设置API密钥。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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); |
当使用windows.web.http命名空间时,对于post而不是formurlencodedcontent,我们编写httpformurlencodedcontent。响应也是httpResponseMessage的类型。其余的都是伊万穆拉夫斯基写下的。
简单的(一行程序,没有错误检查,没有等待响应)解决方案
小心使用!
您可以使用IEnterprise.easy-http,因为它内置了类解析和查询构建:
1 2 3 4 5 6 7 | await new RequestBuilder<ExampleObject>() .SetHost("https://httpbin.org") .SetContentType(ContentType.Application_Json) .SetType(RequestType.Post) .SetModelToSerialize(dto) .Build() .Execute(); |
我是这个库的作者,所以请随意提问或在Github中检查代码。
此解决方案只使用标准.NET调用。
测试:
- 在企业WPF应用程序中使用。使用async/await避免阻塞UI。
- 与.NET 4.5+兼容。
- 无参数测试(需要在后台"获取")。
- 使用参数进行测试(需要在后台"发布")。
- 使用谷歌等标准网页进行测试。
- 使用基于Java的内部WebService进行测试。
参考文献:
1 | // Add a Reference to the assembly System.Web |
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 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"):
1 2 3 4 5 6 | 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"):
1 2 3 4 5 6 | 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. } |
如果您喜欢流畅的API,可以使用tiny.restclient,它在nuget上提供
1 2 3 4 5 6 |
希望有帮助!