在 C# 中通过 POST 发送 JSON 并接收返回的 JSON?
Posted
技术标签:
【中文标题】在 C# 中通过 POST 发送 JSON 并接收返回的 JSON?【英文标题】:Send JSON via POST in C# and Receive the JSON returned? 【发布时间】:2014-05-10 20:23:18 【问题描述】:这是我第一次在我的任何应用程序中使用 JSON 以及 System.Net
和 WebRequest
。我的应用程序应该向身份验证服务器发送一个类似于下面的 JSON 有效负载:
"agent":
"name": "Agent Name",
"version": 1
,
"username": "Username",
"password": "User Password",
"token": "xxxxxx"
为了创建这个有效载荷,我使用了JSON.NET
库。我如何将此数据发送到身份验证服务器并接收其 JSON 响应?这是我在一些示例中看到的,但没有 JSON 内容:
var http = (HttpWebRequest)WebRequest.Create(new Uri(baseUrl));
http.Accept = "application/json";
http.ContentType = "application/json";
http.Method = "POST";
string parsedContent = "Parsed JSON Content needs to go here";
ASCIIEncoding encoding = new ASCIIEncoding();
Byte[] bytes = encoding.GetBytes(parsedContent);
Stream newStream = http.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
var response = http.GetResponse();
var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
但是,与我过去使用过的其他语言相比,这似乎是很多代码。我这样做正确吗?以及如何获取 JSON 响应以便进行解析?
谢谢,精英。
更新代码
// Send the POST Request to the Authentication Server
// Error Here
string json = await Task.Run(() => JsonConvert.SerializeObject(createLoginPayload(usernameTextBox.Text, password)));
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
using (var httpClient = new HttpClient())
// Error here
var httpResponse = await httpClient.PostAsync("URL HERE", httpContent);
if (httpResponse.Content != null)
// Error Here
var responseContent = await httpResponse.Content.ReadAsStringAsync();
【问题讨论】:
你可以试试WebClient.UploadString(JsonConvert.SerializeObjectobj(yourobj))
或HttpClient.PostAsJsonAsync
【参考方案1】:
我发现自己使用HttpClient 库来查询 RESTful API,因为代码非常简单且完全异步。要发送此 JSON 有效负载:
"agent":
"name": "Agent Name",
"version": 1
,
"username": "Username",
"password": "User Password",
"token": "xxxxxx"
有两个类代表您发布的 JSON 结构,可能如下所示:
public class Credentials
public Agent Agent get; set;
public string Username get; set;
public string Password get; set;
public string Token get; set;
public class Agent
public string Name get; set;
public int Version get; set;
您可以使用这样的方法来执行您的 POST 请求:
var payload = new Credentials
Agent = new Agent
Name = "Agent Name",
Version = 1
,
Username = "Username",
Password = "User Password",
Token = "xxxxx"
;
// Serialize our concrete class into a JSON String
var stringPayload = JsonConvert.SerializeObject(payload);
// Wrap our JSON inside a StringContent which then can be used by the HttpClient class
var httpContent = new StringContent(stringPayload, Encoding.UTF8, "application/json");
var httpClient = new HttpClient()
// Do the actual request and await the response
var httpResponse = await httpClient.PostAsync("http://localhost/api/path", httpContent);
// If the response contains content we want to read it!
if (httpResponse.Content != null)
var responseContent = await httpResponse.Content.ReadAsStringAsync();
// From here on you could deserialize the ResponseContent back again to a concrete C# type using Json.Net
【讨论】:
完美,但是 await Task.run(() 是什么? 您不应该在同步 CPU 绑定方法上使用 Task.Run,因为您只是启动一个新线程而没有任何好处! 您不必为每个属性都输入JsonProperty
。只需使用 Json.Net 内置的CamelCasePropertyNamesContractResolver 或custom NamingStrategy
来自定义序列化过程
旁注:不要将using
与HttpClient
一起使用。见:aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
使用 System.Net.Http.Formatting 您定义了扩展方法:"await httpClient.PostAsJsonAsync("api/v1/domain", csObjRequest)"【参考方案2】:
使用 JSON.NET NuGet 包和匿名类型,您可以简化其他发帖人的建议:
// ...
string payload = JsonConvert.SerializeObject(new
agent = new
name = "Agent Name",
version = 1,
,
username = "username",
password = "password",
token = "xxxxx",
);
var client = new HttpClient();
var content = new StringContent(payload, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(uri, content);
// ...
【讨论】:
【参考方案3】:您可以使用JObject
的组合来构建您的HttpContent
来避免和JProperty
,然后在构建StringContent
时调用ToString()
:
/*
"agent":
"name": "Agent Name",
"version": 1
,
"username": "Username",
"password": "User Password",
"token": "xxxxxx"
*/
JObject payLoad = new JObject(
new JProperty("agent",
new JObject(
new JProperty("name", "Agent Name"),
new JProperty("version", 1)
),
new JProperty("username", "Username"),
new JProperty("password", "User Password"),
new JProperty("token", "xxxxxx")
)
);
using (HttpClient client = new HttpClient())
var httpContent = new StringContent(payLoad.ToString(), Encoding.UTF8, "application/json");
using (HttpResponseMessage response = await client.PostAsync(requestUri, httpContent))
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
return JObject.Parse(responseBody);
【讨论】:
如何避免Exception while executing function. Newtonsoft.Json: Can not add Newtonsoft.Json.Linq.JProperty to Newtonsoft.Json.Linq.JArray
错误?
不应使用 using 构造创建 HttpClient 实例。该实例应创建一次并在整个应用程序中使用。这是因为它使用自己的连接池。您的代码大多倾向于抛出 SocketException。 docs.microsoft.com/en-us/dotnet/api/…【参考方案4】:
您还可以使用 HttpClient() 中提供的 PostAsJsonAsync() 方法
var requestObj= JsonConvert.SerializeObject(obj);
HttpResponseMessage response = await client.PostAsJsonAsync($"endpoint",requestObj);
【讨论】:
您能否解释一下您的代码的作用以及它如何解决问题? 你可以使用你想要发布的任何对象并使用 SerializeObject(); 对其进行序列化。var obj= new Credentials Agent = new Agent Name = "Agent Name", Version = 1 , Username = "Username", Password = "User Password", Token = "xxxxx" ;
然后无需将其转换为 httpContent,您可以使用 PostAsJsonAsync() 传递端点 URL 和转换后的 JSON 对象本身。
仅供参考,因为 .NET4.5 左右,HttpClient
上没有 PostAsJsonAsync()
以上是关于在 C# 中通过 POST 发送 JSON 并接收返回的 JSON?的主要内容,如果未能解决你的问题,请参考以下文章
求一个c#的 post请求 json 并且接收返回json数据的一个demo。