[英]How to post JSON to a server using C#?
這是我正在使用的代碼:
// create a request
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create(url); request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.Method = "POST";
// turn our request string into a byte stream
byte[] postBytes = Encoding.UTF8.GetBytes(json);
// this is important - make sure you specify type this way
request.ContentType = "application/json; charset=UTF-8";
request.Accept = "application/json";
request.ContentLength = postBytes.Length;
request.CookieContainer = Cookies;
request.UserAgent = currentUserAgent;
Stream requestStream = request.GetRequestStream();
// now send it
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
// grab te response and print it out to the console along with the status code
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string result;
using (StreamReader rdr = new StreamReader(response.GetResponseStream()))
{
result = rdr.ReadToEnd();
}
return result;
當我運行它時,我總是收到 500 內部服務器錯誤。
我究竟做錯了什么?
我這樣做和工作的方式是:
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{\"user\":\"test\"," +
"\"password\":\"bla\"}";
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
我寫了一個庫以更簡單的方式執行此任務,它在這里: https ://github.com/ademargomes/JsonRequest
Ademar 的解決方案可以通過利用JavaScriptSerializer
的Serialize
方法來提供對象到 JSON 的隱式轉換來改進。
此外,可以利用using
語句的默認功能來省略顯式調用Flush
和Close
。
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
user = "Foo",
password = "Baz"
});
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
HttpClient
類型是比WebClient
和HttpWebRequest
更新的實現。 WebClient
和WebRequest
都已被標記為過時。 [1]
您可以簡單地使用以下幾行。
string myJson = "{'Username': 'myusername','Password':'pass'}";
using (var client = new HttpClient())
{
var response = await client.PostAsync(
"http://yourUrl",
new StringContent(myJson, Encoding.UTF8, "application/json"));
}
當您多次需要HttpClient
時,建議只創建一個實例並重用它或使用新的HttpClientFactory
。 [2]
對於 FTP,由於 HttpClient 不支持,我們建議使用第三方庫。
@docs.microsoft.com [3]
從 dotnet core 3.1 開始,您可以使用System.Text.Json
中的JsonSerializer
創建您的 json 字符串。
string myJson = JsonSerializer.Serialize(credentialsObj);
在 Sean 的帖子之后,沒有必要嵌套 using 語句。 通過using
StreamWriter 它將在塊的末尾刷新和關閉,因此無需顯式調用Flush()
和Close()
方法:
var request = (HttpWebRequest)WebRequest.Create("http://url");
request.ContentType = "application/json";
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string json = new JavaScriptSerializer().Serialize(new
{
user = "Foo",
password = "Baz"
});
streamWriter.Write(json);
}
var response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
如果您需要異步調用,請使用
var request = HttpWebRequest.Create("http://www.maplegraphservices.com/tokkri/webservices/updateProfile.php?oldEmailID=" + App.currentUser.email) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "text/json";
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the stream request operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
// Create the post data
string postData = JsonConvert.SerializeObject(edit).ToString();
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
//Start the web request
request.BeginGetResponse(new AsyncCallback(GetResponceStreamCallback), request);
}
void GetResponceStreamCallback(IAsyncResult callbackResult)
{
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
{
string result = httpWebStreamReader.ReadToEnd();
stat.Text = result;
}
}
我最近想出了一種更簡單的方法來發布 JSON,並增加了從我的應用程序中的模型轉換的額外步驟。 請注意,您必須為控制器創建模型[JsonObject]
才能獲取值並進行轉換。
要求:
var model = new MyModel();
using (var client = new HttpClient())
{
var uri = new Uri("XXXXXXXXX");
var json = new JavaScriptSerializer().Serialize(model);
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PutAsync(uri,stringContent).Result;
// ...
}
模型:
[JsonObject]
[Serializable]
public class MyModel
{
public Decimal Value { get; set; }
public string Project { get; set; }
public string FilePath { get; set; }
public string FileName { get; set; }
}
服務器端:
[HttpPut]
public async Task<HttpResponseMessage> PutApi([FromBody]MyModel model)
{
// ...
}
警告! 我對這個問題有非常強烈的看法。
.NET 現有的 Web 客戶端對開發人員不友好! WebRequest和WebClient是“如何挫敗開發人員”的主要例子。 它們很冗長且使用起來很復雜; 當您只想在 C# 中執行一個簡單的 Post 請求時。 HttpClient在解決這些問題方面做了一些工作,但仍然不足。 最重要的是,微軟的文檔很糟糕……真的很糟糕; 除非您想篩選一頁又一頁的技術簡介。
開源來救援。 有三個優秀的開源免費 NuGet 庫可供選擇。 謝天謝地! 這些都得到了很好的支持,記錄在案,是的,很容易 - 更正......超級容易 - 使用。
它們之間沒有太多區別,但我會給 ServiceStack.Text 一點優勢……
好的 - 那么 JSON 格式的 Post 請求在 ServiceStack.Text 中是什么樣的?
var response = "http://example.org/login"
.PostJsonToUrl(new Login { Username="admin", Password="mypassword" });
那是一行代碼。 簡潔輕松! 將上述內容與 .NET 的 Http 庫進行比較。
未提及此選項:
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:9000/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var foo = new User
{
user = "Foo",
password = "Baz"
}
await client.PostAsJsonAsync("users/add", foo);
}
實現此目的的一些不同且干凈的方法是使用 HttpClient ,如下所示:
public async Task<HttpResponseMessage> PostResult(string url, ResultObject resultObject)
{
using (var client = new HttpClient())
{
HttpResponseMessage response = new HttpResponseMessage();
try
{
response = await client.PostAsJsonAsync(url, resultObject);
}
catch (Exception ex)
{
throw ex
}
return response;
}
}
我終於通過包含.Result在同步模式下調用
HttpResponseMessage response = null;
try
{
using (var client = new HttpClient())
{
response = client.PostAsync(
"http://localhost:8000/....",
new StringContent(myJson,Encoding.UTF8,"application/json")).Result;
if (response.IsSuccessStatusCode)
{
MessageBox.Show("OK");
}
else
{
MessageBox.Show("NOK");
}
}
}
catch (Exception ex)
{
MessageBox.Show("ERROR");
}
我發現這是發布讀取 JSON 數據的最友好和最簡潔的方式:
var url = @"http://www.myapi.com/";
var request = new Request { Greeting = "Hello world!" };
var json = JsonSerializer.Serialize<Request>(request);
using (WebClient client = new WebClient())
{
var jsonResponse = client.UploadString(url, json);
var response = JsonSerializer.Deserialize<Response>(jsonResponse);
}
我正在使用 Microsoft 的System.Text.Json
對 JSON 進行序列化和反序列化。 請參閱NuGet 。
我就是這樣做的
//URL
var url = "http://www.myapi.com/";
//Request
using var request = new HttpRequestMessage(HttpMethod.Post, url);
//Headers
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Cache-Control", "no-cache");
//Payload
var payload = JsonConvert.SerializeObject(
new
{
Text = "Hello world"
});
request.Content = new StringContent(payload, Encoding.UTF8, "application/json");
//Send
var response = await _httpClient.SendAsync(request);
//Handle response
if (response.IsSuccessStatusCode)
return;
首先使用Newtonsoft.Json
然后編寫這樣的方法:
public static string? LoginToken()
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://url");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
// write your json content here
string json = JsonConvert.SerializeObject(new
{
userName = ApiOptions.Username,
password = ApiOptions.Password
}
);
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
return result;
}
}
此方法返回string
。 如果要將string
結果反序列化為JSON
,只需在方法末尾添加以下行:
var result = streamReader.ReadToEnd();
var json_result = JsonConvert.DeserializeObject<LoginTokenResponse>(result); // + add this code
哪個LoginTokenResponse
是您要反序列化字符串結果的自定義類
var data = Encoding.ASCII.GetBytes(json);
byte[] postBytes = Encoding.UTF8.GetBytes(json);
使用 ASCII 而不是 UFT8
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.