에서 HTTP POST 요청을 보냅니다.그물
HTTP POST 요청을 하고 본문에서 데이터를 전송하려면 어떻게 해야 합니까?
HTTP GET 및 POST 요청을 수행하는 몇 가지 방법은 다음과 같습니다.
방법 A: HttpClient(기본 설정)
다음에서 사용할 수 있습니다.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();
종속성 주입 솔루션은 을 참조하십시오.
포스트.
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();얻다
var responseString = await client.GetStringAsync("http://www.example.com/recepticle.aspx");
방법 B: 타사 라이브러리
포스트.
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;
포스트.
var responseString = await "http://www.example.com/recepticle.aspx" .PostUrlEncodedAsync(new { thing1 = "hello", thing2 = "world" }) .ReceiveString();GETvar responseString = await "http://www.example.com/recepticle.aspx" .GetStringAsync();
방법 C: HttpWebRequest(새 작업에 권장되지 않음)
다음에서 사용할 수 있습니다.NET Framework 1.1+, .NET 준 2.0+, .NET Core 1.0 버전.Core에서는 합니다.NET Core에서는 대부분 호환성을 위해 랩을 합니다.HttpClient성능이 떨어지고 새로운 기능을 사용하지 않습니다.
using System.Net;
using System.Text; // For class Encoding
using System.IO; // For StreamReader
포스트.
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();얻다
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(새 작업에는 권장되지 않음)
이것은 주위의 포장지입니다.HttpWebRequest와 비교해 보십시오.
다음에서 사용할 수 있습니다.NET Framework 1.1+, NET Standard 2.0+ 및 .NET Core 2.0 이상.
상황에서는(. 4해야 할 경우 NET Framework 4.5-4.8), HTTP 요청 시,WebClient여전히 사용할 수 있습니다.
using System.Net;
using System.Collections.Specialized;
포스트.
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); }얻다
using (var client = new WebClient()) { var responseString = client.DownloadString("http://www.example.com/recepticle.aspx"); }
단순 GET 요청
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);
지금까지 찾은 간단한 솔루션(단일 라이너, 오류 확인 없음, 응답 대기 없음):
(new WebClient()).UploadStringAsync(new Uri(Address), dataString);
조심해서 사용하세요!
이 솔루션은 표준만 사용합니다.NET 통화.
테스트됨:
- 엔터프라이즈 WPF 응용 프로그램에서 사용 중입니다.비동기/대기를 사용하여 UI를 차단하지 않습니다.
- 와 호환됩니다.NET 4.5+.
- 파라미터 없이 테스트합니다(후면에 "GET" 필요).
- 파라미터로 테스트합니다(후면에 "POST" 필요).
- Google과 같은 표준 웹 페이지로 테스트했습니다.
- 내부 Java 기반 웹 서비스로 테스트되었습니다.
참조:
// 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.
}
당신이 유창한 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>();
하지만 또 다른 방법은 다음과 같습니다.
using (HttpClient httpClient = new HttpClient())
using (MultipartFormDataContent form = new MultipartFormDataContent())
{
form.Add(new StringContent(param1), "param1");
form.Add(new StringContent(param2), "param2");
using (HttpResponseMessage response = await httpClient.PostAsync(url, form))
{
response.EnsureSuccessStatusCode();
string res = await response.Content.ReadAsStringAsync();
return res;
}
}
이렇게 하면 스트림을 쉽게 게시할 수 있습니다.
Windows를 사용하는 경우.Web.Http 네임스페이스는 FormUrlEncodedContent 대신 POST에 HttpFormUrlEncodedContent를 씁니다.또한 응답은 HttpResponseMessage 유형입니다.나머지는 Evan Mulawski가 기록한 대로입니다.
왜 이것이 완전히 사소하지 않습니까?요청을 수행하는 것은 특히 결과를 처리하지 않습니다.그리고 몇 개가 있는 것 같습니다.NET 버그도 관련되어 있습니다. HttpClient의 버그를 참조하십시오.GetAsync는 TaskCancelledException이 아닌 WebException을 슬로우해야 합니다.
저는 결국 이 코드로 끝났습니다.
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());
}
}
이는 다음과 같은 경우에 따라 GET 또는 POST를 수행합니다.postBuffer 는 null입니다.
성공이 참일 경우 응답은 다음과 같습니다.ResponseAsString.
성공이 거짓이면 확인할 수 있습니다.WebExceptionStatus,HttpStatusCode그리고.ResponseAsString무엇이 잘못되었는지 확인하려고 노력합니다.
다음은 HTTPS 웹 요청의 예입니다.PHP 스크립트에서 모든 결과를 에코할 수 있습니다.마지막으로, PHP 에코 문자열이 C# 클라이언트 측에서 경고로 표시됩니다.
string url = "https://mydomain.ir/test1.php";
StringBuilder postData = new StringBuilder();
postData.Append(String.Format("{0}={1}&", HttpUtility.HtmlEncode("username"), HttpUtility.HtmlEncode("ali")));
postData.Append(String.Format("{0}={1}", HttpUtility.HtmlEncode("password"), HttpUtility.HtmlEncode("123456789")));
StringContent myStringContent = new StringContent(postData.ToString(), Encoding.UTF8, "application/x-www-form-urlencoded");
HttpClient client = new HttpClient();
HttpResponseMessage message = client.PostAsync(url, myStringContent).GetAwaiter().GetResult();
string responseContent = message.Content.ReadAsStringAsync().GetAwaiter().GetResult();
DisplayAlert("Your Feedback", responseContent, "OK");
PHP 서버 측:
<?php
if (isset($_POST["username"]) && $_POST["username"] == "ali") {
echo "Yes, hi Ali";
}
else {
echo "No, where is Ali?";
}
?>
결과는 "네, 안녕 알리"가 될 것입니다.
이것은 사마린 양식을 위한 것입니다.C#의 경우.NET 응용 프로그램, 표시 바꾸기경고:
MessageBox.show(responseContent);
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");
JSON 메시지 본문을 게시해야 하는 경우 다음을 사용할 수 있습니다.이름이 m인 클래스 인스턴스가 있다고 가정합니다.
string jsonMessage = JsonConvert.SerializeObject(m);
// Make POST call
using (HttpClient client = new HttpClient())
{
HttpRequestMessage requestMessage = new
HttpRequestMessage(HttpMethod.Post, "<url here>");
requestMessage.Content = new StringContent(jsonMessage, Encoding.UTF8, "application/json");
HttpResponseMessage response = client.SendAsync(requestMessage).Result;
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
// Do something here
}
}
.NET Core에서 다음 코드로 POST 통화를 할 수 있습니다.여기서 이 코드에 몇 가지 추가 기능을 추가했습니다. 따라서 프록시 및 네트워크 자격 증명(있는 경우)을 사용하여 코드를 작동시킬 수 있습니다.
또한 메시지의 인코딩을 변경할 수 있습니다.
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;
}
여기 제가 사용하는 것이 있습니다.HTTP POST 요청을 만드는 NET 4.8.이 코드를 사용하면 한 번에 여러 POST 요청을 비동기식으로 보낼 수 있습니다.
각 요청이 끝날 때마다 이벤트가 발생합니다.또한 모든 요청이 끝나면 다른 이벤트가 발생합니다.
다음은 코어 클래스입니다.
Imports System.ComponentModel
Imports System.Text.RegularExpressions
Imports System.Timers
Imports System.Windows.Forms
Imports AeonLabs
Imports AeonLabs.Environment
Imports Newtonsoft.Json
Public Class HttpDataCore
Public Property url As String
Public Property state As New environmentVarsCore
Public Property errorMessage As String = ""
Public Property statusMessage As String
Public Property threadCount As Integer = 25
Public Property numberOfRetryAttempts = 5
Public Property queue As List(Of _queue_data_struct)
Public Property queueBWorker As Integer() ' has the size of threadCount
Public Property queueLock As New Object
Public Property retryAttempts As New _retry_attempts
Public Property dataStatistics As List(Of _data_statistics)
Public Property loadingCounter As Integer
Public Property CompletionPercentage As Integer ' value range 0-100
Public Property IsBusy As Boolean
Public Structure _queue_data_struct
Dim vars As Dictionary(Of String, String)
Dim filenameOrSavePath As String ' full address file name or full adress folder path
Dim misc As Dictionary(Of String, String)
Dim status As Integer ' -1 - completed; 0- not sent yet; 1-already sent / processing
End Structure
Public Structure _retry_attempts
Dim counter As Integer
Dim pattern As Integer
Dim previousPattern As Integer
Dim errorMessage As String
End Structure
Public Structure _data_statistics
Dim filesize As Double
Dim bytesSentReceived As Double
Dim speed As Double
End Structure
Public WithEvents RestartQueueTimer As New Timers.Timer
Public bwDataRequest() As BackgroundWorker
Public Event requestCompleted(sender As Object, requestData As String) 'TODO add misc vars
Private sendToQueue As Boolean
Public Sub New(ByVal Optional _state As environmentVarsCore = Nothing, ByVal Optional _url As String = "")
queue = New List(Of _queue_data_struct)
dataStatistics = New List(Of _data_statistics)
loadingCounter = 0
sendToQueue = False
If _state IsNot Nothing AndAlso _url.Equals("") Then
url = _state.ServerBaseAddr & _state.ApiServerAddrPath
ElseIf Not _url.Equals("") Then
url = _url
Else
Throw New System.Exception("Initialization err: state and url cannot be both null at same time")
End If
If _state IsNot Nothing Then
state = _state
End If
End Sub
Public Sub loadQueue(ByVal vars As Dictionary(Of String, String), ByVal Optional misc As Dictionary(Of String, String) = Nothing, ByVal Optional filenameOrSavePath As String = Nothing)
Dim queueItem As New _queue_data_struct
queueItem.vars = New Dictionary(Of String, String)
queueItem.misc = New Dictionary(Of String, String)
queueItem.vars = vars
queueItem.status = 0
queueItem.misc = misc
queueItem.filenameOrSavePath = filenameOrSavePath
queue.Add(queueItem)
End Sub
Public Sub clearQueue()
loadingCounter = 0
queue = New List(Of _queue_data_struct)
End Sub
Public Sub startRequest()
If bwDataRequest(0) Is Nothing Then
Throw New Exception("You need to call initialze first")
Exit Sub
End If
'startSendQueue()
IsBusy = True
AddHandler RestartQueueTimer.Elapsed, New ElapsedEventHandler(AddressOf QueueTimerTick)
With RestartQueueTimer
.Enabled = True
.Interval = 500
.Start()
End With
End Sub
Private Sub QueueTimerTick(ByVal sender As Object, ByVal e As ElapsedEventArgs)
If QueuesToComplete(queue).Equals(0) And QueuesToSend(queue).Equals(0) Then
RestartQueueTimer.Stop()
queue = New List(Of _queue_data_struct)
RaiseEvent requestCompleted(Me, Nothing)
IsBusy = False
Exit Sub
End If
If retryAttempts.counter >= numberOfRetryAttempts Then 'ToDo a retry number of attempts before quits
Threading.Thread.CurrentThread.CurrentUICulture = Globalization.CultureInfo.GetCultureInfo(state.currentLang)
Dim MsgBox As messageBoxForm
MsgBox = New messageBoxForm(retryAttempts.errorMessage & ". " & My.Resources.strings.tryAgain & " ?", My.Resources.strings.question, MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If MsgBox.ShowDialog() = DialogResult.Yes Then
Dim retry As _retry_attempts
With retry
.counter = 0
.previousPattern = -1
.pattern = 0
.errorMessage = ""
End With
retryAttempts = retry
startSendQueue()
Else
RestartQueueTimer.Stop()
queue = New List(Of _queue_data_struct)
RaiseEvent requestCompleted(Me, Nothing)
IsBusy = False
Exit Sub
End If
Exit Sub
ElseIf Not sendToQueue And QueuesToSend(queue) > 0 Then
startSendQueue()
End If
End Sub
Private Sub startSendQueue()
sendToQueue = True
While QueuesToSend(queue) > 0
For shtIndex = 0 To threadCount
For i = 0 To queue.Count - 1
If Not bwDataRequest(shtIndex).IsBusy Then
SyncLock queueLock
If queue.ElementAt(i).status.Equals(0) Then
Dim data As New _queue_data_struct
data.vars = queue.ElementAt(i).vars
data.status = 1
data.misc = queue.ElementAt(i).misc
data.filenameOrSavePath = queue.ElementAt(i).filenameOrSavePath
queue(i) = data
queueBWorker(shtIndex) = i
dataStatistics(shtIndex) = (New _data_statistics)
bwDataRequest(shtIndex).RunWorkerAsync(queue(i))
Threading.Thread.Sleep(50)
End If
End SyncLock
End If
Next i
Next shtIndex
End While
sendToQueue = False
End Sub
Public Function QueuesToSend(queue As List(Of _queue_data_struct)) As Integer
Dim counter As Integer = 0
For i = 0 To queue.Count - 1
If queue(i).status.Equals(0) Then
counter += 1
End If
Next i
Return counter
End Function
Public Function QueuesToComplete(queue As List(Of _queue_data_struct)) As Integer
Dim counter As Integer = 0
For i = 0 To queue.Count - 1
If queue(i).status.Equals(1) Then
counter += 1
End If
Next i
Return counter
End Function
Public Function QueuesMultiHash(queue As List(Of _queue_data_struct)) As Integer
Dim counter As Integer = 0
For i = 0 To queue.Count - 1
If queue(i).status.Equals(1) Then
counter += i
End If
Next i
Return counter
End Function
Public Function IsBase64String(ByVal s As String) As Boolean
s = s.Trim()
Return (s.Length Mod 4 = 0) AndAlso Regex.IsMatch(s, "^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None)
End Function
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Public Function ConvertDataToArray(key As String, fields As String(), response As String) As Dictionary(Of String, List(Of String))
If GetMessage(response).Equals("1001") Then
Threading.Thread.CurrentThread.CurrentUICulture = Globalization.CultureInfo.GetCultureInfo(state.currentLang)
errorMessage = "{'error':true,'message':'" & My.Resources.strings.errorNoRecordsFound & "'}"
Return Nothing
End If
Try
Dim jsonResult = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(response)
If jsonResult.ContainsKey(key) Then
If Not jsonResult.Item(key).item(0).Count.Equals(fields.Length) Then
Threading.Thread.CurrentThread.CurrentUICulture = Globalization.CultureInfo.GetCultureInfo(state.currentLang)
errorMessage = "{'error':true,'message':'" & My.Resources.strings.JsonFieldsMismatch & ". table(" & key & "'}"
Return Nothing
Else
Dim results = New Dictionary(Of String, List(Of String))
For k = 0 To fields.Length - 1
Dim fieldValues As List(Of String) = New List(Of String)
For i = 0 To jsonResult.Item(key).Count - 1
fieldValues.Add(jsonResult.Item(key).item(i).item(k).ToString)
Next i
results.Add(fields(k), fieldValues)
Next k
Return results
End If
Else
Threading.Thread.CurrentThread.CurrentUICulture = Globalization.CultureInfo.GetCultureInfo(state.currentLang)
errorMessage = "{'error':true,'message':'" & My.Resources.strings.JsonkeyNotFound & " (" & key & "'}"
Return Nothing
End If
Catch ex As Exception
errorMessage = "{'error':true,'message':'" & ex.ToString & "'}"
errorMessage = ex.ToString
Return Nothing
End Try
End Function
End Class
그AeonLabs.Envoriment집합 또는 필드와 속성이 있는 클래스입니다.
다음 중 하나는 POST 요청을 하기 위한 것입니다.
Imports System.ComponentModel
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Web
Imports System.Web.Script.Serialization
Imports System.Windows.Forms
Imports AeonLabs.Environment
Imports AeonLabs.Security
Public Class HttpDataPostData
Inherits HttpDataCore
Public Event updateProgress(sender As Object, misc As Dictionary(Of String, String))
Public Event dataArrived(sender As Object, requestData As String, misc As Dictionary(Of String, String))
Public Sub New(ByVal Optional _state As environmentVarsCore = Nothing, ByVal Optional _url As String = "")
MyBase.New(_state, _url)
End Sub
Public Sub initialize(ByVal Optional _threadCount As Integer = 0)
If Not _threadCount.Equals(0) Then
threadCount = _threadCount
End If
ReDim bwDataRequest(threadCount)
ReDim queueBWorker(threadCount)
For shtIndex = 0 To threadCount
dataStatistics.Add(New _data_statistics)
bwDataRequest(shtIndex) = New System.ComponentModel.BackgroundWorker
bwDataRequest(shtIndex).WorkerReportsProgress = True
bwDataRequest(shtIndex).WorkerSupportsCancellation = True
AddHandler bwDataRequest(shtIndex).DoWork, AddressOf bwDataRequest_DoWork
AddHandler bwDataRequest(shtIndex).RunWorkerCompleted, AddressOf bwDataRequest_RunWorkerCompleted
Next shtIndex
Dim retry As _retry_attempts
With retry
.counter = 0
.previousPattern = -1
.pattern = 0
.errorMessage = ""
End With
retryAttempts = retry
End Sub
Private Sub bwDataRequest_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
' Find out the Index of the bWorker that called this DoWork (could be cleaner, I know)
Dim Y As Integer
Dim Index As Integer = Nothing
For Y = 0 To UBound(bwDataRequest)
If sender.Equals(bwDataRequest(Y)) Then
Index = Y
Exit For
End If
Next Y
Dim queue As _queue_data_struct
queue = e.Argument
Dim vars As New Dictionary(Of String, String)
vars = queue.vars
'TODO translation need to be local
If Not System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable() Then
Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(state.currentLang)
e.Result = "{'error':true,'message':'" & My.Resources.strings.errorNoNetwork & "'}"
Exit Sub
End If
If vars Is Nothing Then
e.Result = "{'error':true,'message':'missconfiguration vars'}"
Exit Sub
End If
If Not vars.ContainsKey("id") Then
vars.Add("id", state.userId)
End If
If Not vars.ContainsKey("pid") Then
Dim appId As New FingerPrint
vars.Add("pid", appId.Value)
End If
If Not vars.ContainsKey("language") Then
vars.Add("language", state.currentLang)
End If
If Not vars.ContainsKey("origin") Then
vars.Add("origin", state.softwareAccessMode)
End If
Dim serializer As New JavaScriptSerializer()
Dim json As String = serializer.Serialize(vars)
Dim encryption As New AesCipher(state)
Dim encrypted As String = HttpUtility.UrlEncode(encryption.encrypt(json))
Dim PostData = "origin=" & state.softwareAccessMode & "&data=" & encrypted
Dim request As WebRequest = WebRequest.Create(url)
Dim responseFromServer As String = ""
Dim decrypted As String = ""
request.Method = "POST"
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(PostData)
request.ContentType = "application/x-www-form-urlencoded"
request.Headers.Add("Authorization", state.ApiHttpHeaderToken & "-" & state.softwareAccessMode)
request.ContentLength = byteArray.Length
Try
Dim dataStream As Stream = request.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
dataStream.Close()
Dim response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
dataStream = response.GetResponseStream()
Dim reader As New StreamReader(dataStream)
responseFromServer = reader.ReadToEnd()
reader.Close()
dataStream.Close()
response.Close()
If response.StatusCode = HttpStatusCode.Accepted Or response.StatusCode = 200 Then
If IsBase64String(responseFromServer) And Not responseFromServer.Equals("") Then
decrypted = encryption.decrypt((responseFromServer)).Replace("\'", "'")
Else
Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(state.currentLang)
decrypted = "{'error':true,'encrypted':false,'message':'" & My.Resources.strings.contactingCommServer & " |" & responseFromServer & "|'}"
End If
Else
Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(state.currentLang)
decrypted = "{'error':true,'message':'" & My.Resources.strings.contactingCommServer & " (" & response.StatusCode & ")', 'statuscode':'" & response.StatusCode & "'}"
End If
Catch ex As Exception
Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(state.currentLang)
decrypted = "{'error':true,'message':'" & My.Resources.strings.contactingCommServer & " (" & ex.Message.ToString.Replace("'", "\'") & ")'}"
End Try
e.Result = decrypted.Replace("\'", "'")
End Sub
Private Sub bwDataRequest_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
' Find out the Index of the bWorker that called this DoWork (could be cleaner, I know)
Dim Y As Integer
Dim Index As Integer = Nothing
Dim data As New _queue_data_struct
For Y = 0 To UBound(bwDataRequest)
If sender.Equals(bwDataRequest(Y)) Then
Index = Y
Exit For
End If
Next Y
If IsResponseOk(e.Result, "statuscode") Then
data = New _queue_data_struct
data = queue(queueBWorker(Index))
data.status = 0 're queue the file
SyncLock queueLock
queue(queueBWorker(Index)) = data
End SyncLock
Dim errorMsg As String = GetMessage(e.Result)
Dim retry As _retry_attempts
With retry
.counter = retryAttempts.counter
.previousPattern = retryAttempts.previousPattern
.pattern = retryAttempts.pattern
.errorMessage = retryAttempts.errorMessage
End With
retry.errorMessage = If(retryAttempts.errorMessage.IndexOf(errorMsg) > -1, retryAttempts.errorMessage, retryAttempts.errorMessage & System.Environment.NewLine & errorMsg)
retry.pattern = QueuesMultiHash(queue)
If retry.previousPattern.Equals(retry.pattern) Then
retry.counter += 1
Else
retry.counter = 1
retry.previousPattern = retryAttempts.pattern
End If
retryAttempts = retry
Exit Sub
End If
data = New _queue_data_struct
data = queue(queueBWorker(Index))
data.status = -1 'completed sucessfully status
SyncLock queueLock
queue(queueBWorker(Index)) = data
End SyncLock
loadingCounter += 1
CompletionPercentage = (loadingCounter / queue.Count) * 100
statusMessage = "Loading data from the cloud..."
RaiseEvent updateProgress(Me, queue(queueBWorker(Index)).misc)
RaiseEvent dataArrived(Me, e.Result, queue(queueBWorker(Index)).misc)
End Sub
End Class
Aoenlabs.보안은 표준 암호화 알고리즘을 사용하여 암호화된 POST 데이터를 전송하는 클래스입니다.
언급URL : https://stackoverflow.com/questions/4015324/send-http-post-request-in-net
'programing' 카테고리의 다른 글
| 가장 유용한 NLog 구성 (0) | 2023.05.02 |
|---|---|
| 파이썬에서 목록의 요소 수(목록 길이)를 가져오려면 어떻게 해야 합니까? (0) | 2023.05.02 |
| 파이썬에서 목록의 모든 숫자에서 값을 빼시겠습니까? (0) | 2023.05.02 |
| 스프링 데이터가 있는 MongoRepository에서 쿼리 주석을 사용하는 동안 쿼리를 표시하는 방법 (0) | 2023.05.02 |
| Mongoid를 사용한 배치 삽입/업데이트? (0) | 2023.05.02 |