คำตอบ:
มีหลายวิธีในการดำเนินการ HTTP GET
และPOST
คำขอ:
.NET Framework 4.5+
ที่มีจำหน่ายใน: .NET Standard 1.1+
, .NET Core 1.0+
,
ปัจจุบันเป็นวิธีการที่ต้องการและไม่ตรงกันและมีประสิทธิภาพสูง ใช้ในตัวรุ่นในกรณีส่วนใหญ่ แต่สำหรับแพลตฟอร์มเก่ามากมีแพคเกจ NuGet
using System.Net.Http;
ขอแนะนำให้สร้างอินสแตนซ์หนึ่งHttpClient
สำหรับอายุการใช้งานของแอปพลิเคชันของคุณและแชร์เว้นแต่คุณจะมีเหตุผลเฉพาะที่ไม่ควรทำ
private static readonly HttpClient client = new HttpClient();
ดูHttpClientFactory
วิธีการแก้ปัญหาการฉีดพึ่งพา
POST
var values = new Dictionary<string, string>
{
{ "thing1", "hello" },
{ "thing2", "world" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://www.example.com/recepticle.aspx", content);
var responseString = await response.Content.ReadAsStringAsync();
GET
var responseString = await client.GetStringAsync("http://www.example.com/recepticle.aspx");
POST
var client = new RestClient("http://example.com");
// client.Authenticator = new HttpBasicAuthenticator(username, password);
var request = new RestRequest("resource/{id}");
request.AddParameter("thing1", "Hello");
request.AddParameter("thing2", "world");
request.AddHeader("header", "value");
request.AddFile("file", path);
var response = client.Post(request);
var content = response.Content; // Raw content as string
var response2 = client.Post<Person>(request);
var name = response2.Data.Name;
มันเป็นห้องสมุดที่ใหม่กว่าที่มี API ที่คล่องแคล่วทดสอบผู้ช่วยใช้ HttpClient ภายใต้ประทุนและเป็นแบบพกพา มันสามารถใช้ได้ผ่านNuGet
using Flurl.Http;
POST
var responseString = await "http://www.example.com/recepticle.aspx"
.PostUrlEncodedAsync(new { thing1 = "hello", thing2 = "world" })
.ReceiveString();
GET
var responseString = await "http://www.example.com/recepticle.aspx"
.GetStringAsync();
.NET Framework 1.1+
ที่มีจำหน่ายใน: .NET Standard 2.0+
, .NET Core 1.0+
, ใน. NET Core เป็นส่วนใหญ่สำหรับความเข้ากันได้ - มันล้อมรอบHttpClient
มีประสิทธิภาพน้อยกว่าและจะไม่ได้รับคุณสมบัติใหม่
using System.Net;
using System.Text; // For class Encoding
using System.IO; // For StreamReader
POST
var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx");
var postData = "thing1=" + Uri.EscapeDataString("hello");
postData += "&thing2=" + Uri.EscapeDataString("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();
GET
var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx");
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
HttpWebRequest
นี่คือเสื้อคลุมรอบ เปรียบกับHttpClient
ที่มีจำหน่ายใน: .NET Framework 1.1+
, NET Standard 2.0+
,.NET Core 2.0+
using System.Net;
using System.Collections.Specialized;
POST
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["thing1"] = "hello";
values["thing2"] = "world";
var response = client.UploadValues("http://www.example.com/recepticle.aspx", values);
var responseString = Encoding.Default.GetString(response);
}
GET
using (var client = new WebClient())
{
var responseString = client.DownloadString("http://www.example.com/recepticle.aspx");
}
response.Result.Content.ReadAsStringAsync()
รับคำของ่ายๆ
using System.Net;
...
using (var wb = new WebClient())
{
var response = wb.DownloadString(url);
}
คำขอ POST ง่าย ๆ
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มีตัวอย่าง
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 ฉันใช้Visual Studio 2013 Express Edition:
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 ด้วย
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);
วิธีนี้ใช้ไม่ได้เลยยกเว้นการเรียก. NET แบบมาตรฐาน
การทดสอบ:
อ้างอิง:
// 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.
}
Simple (one-liner, ไม่มีการตรวจสอบข้อผิดพลาด, ไม่ต้องรอการตอบกลับ) โซลูชันที่ฉันพบ:
(new WebClient()).UploadStringAsync(new Uri(Address), dataString);
ใช้ด้วยความระมัดระวัง!
เมื่อใช้Windows.Web.Http namespace สำหรับ POST แทน FormUrlEncodedContent เราจะเขียน HttpFormUrlEncodedContent นอกจากนี้การตอบสนองเป็นประเภทของ HttpResponseMessage ที่เหลือก็คือ Evan Mulawski ที่จดไว้
ถ้าคุณชอบได้อย่างคล่องแคล่ว 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 บางส่วนที่เกี่ยวข้องเช่นกัน - ดูข้อผิดพลาดใน HttpClient.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());
}
} 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());
}
}
สิ่งนี้จะทำ GET หรือ POST ขึ้นอยู่กับว่าpostBuffer
เป็นโมฆะหรือไม่
หากความสำเร็จเป็นจริงคำตอบก็จะอยู่ในนั้น ResponseAsString
ถ้าประสบความสำเร็จเป็นเท็จคุณสามารถตรวจสอบWebExceptionStatus
, HttpStatusCode
และResponseAsString
พยายามที่จะเห็นสิ่งที่ผิดพลาดไป
ใน. net core คุณสามารถทำการ post-call ด้วยรหัสต่อไปนี้ที่นี่ฉันได้เพิ่มคุณสมบัติพิเศษบางอย่างในรหัสนี้เพื่อให้รหัสของคุณทำงานหลังพร็อกซีและมีข้อมูลประจำตัวเครือข่ายถ้ามีที่นี่ฉันพูดถึงว่าคุณสามารถเปลี่ยนการเข้ารหัส ข้อความของคุณ. ฉันหวังว่าสิ่งนี้จะอธิบายทั้งหมดและช่วยคุณในการเขียนโปรแกรม
HttpClient client = GetHttpClient(_config);
if (headers != null)
{
foreach (var header in headers)
{
client.DefaultRequestHeaders.TryAddWithoutValidation(header.Key, header.Value);
}
}
client.BaseAddress = new Uri(baseAddress);
Encoding encoding = Encoding.UTF8;
var result = await client.PostAsync(url, new StringContent(body, encoding, "application/json")).ConfigureAwait(false);
if (result.IsSuccessStatusCode)
{
return new RequestResponse { severity = "Success", httpResponse = result.Content.ReadAsStringAsync().Result, StatusCode = result.StatusCode };
}
else
{
return new RequestResponse { severity = "failure", httpResponse = result.Content.ReadAsStringAsync().Result, StatusCode = result.StatusCode };
}
public HttpClient GetHttpClient(IConfiguration _config)
{
bool ProxyEnable = Convert.ToBoolean(_config["GlobalSettings:ProxyEnable"]);
HttpClient client = null;
if (!ProxyEnable)
{
client = new HttpClient();
}
else
{
string ProxyURL = _config["GlobalSettings:ProxyURL"];
string ProxyUserName = _config["GlobalSettings:ProxyUserName"];
string ProxyPassword = _config["GlobalSettings:ProxyPassword"];
string[] ExceptionURL = _config["GlobalSettings:ExceptionURL"].Split(';');
bool BypassProxyOnLocal = Convert.ToBoolean(_config["GlobalSettings:BypassProxyOnLocal"]);
bool UseDefaultCredentials = Convert.ToBoolean(_config["GlobalSettings:UseDefaultCredentials"]);
WebProxy proxy = new WebProxy
{
Address = new Uri(ProxyURL),
BypassProxyOnLocal = BypassProxyOnLocal,
UseDefaultCredentials = UseDefaultCredentials,
BypassList = ExceptionURL,
Credentials = new NetworkCredential(ProxyUserName, ProxyPassword)
};
HttpClientHandler handler = new HttpClientHandler { Proxy = proxy };
client = new HttpClient(handler,true);
}
return client;
}
HttpWebResponse response = (HttpWebResponse)HttpWReq.GetResponse();