在C#中通过POST发送JSON并接收返回的JSON?

Hun*_*ell 63 .net c# json httpwebrequest json.net

这是我第一次曾经使用JSON,甚至System.NetWebRequest部分在我的任何应用程序.我的应用程序应该发送一个JSON有效负载,类似于下面的一个到身份验证服务器:

{
  "agent": {                             
    "name": "Agent Name",                
    "version": 1                                                          
  },
  "username": "Username",                                   
  "password": "User Password",
  "token": "xxxxxx"
}
Run Code Online (Sandbox Code Playgroud)

为了创建这个有效载荷,我使用了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();
Run Code Online (Sandbox Code Playgroud)

然而,这似乎是很多代码与使用我过去使用过的其他语言相比较.我这样做是否正确?我将如何获得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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Kai*_*ger 95

我发现自己使用HttpClient库来查询RESTful API,因为代码非常简单且完全异步.

有两个代表您发布的JSON-Structure的类可能如下所示:

{
  "agent": {                             
    "name": "Agent Name",                
    "version": 1                                                          
  },
  "username": "Username",                                   
  "password": "User Password",
  "token": "xxxxxx"
}
Run Code Online (Sandbox Code Playgroud)

你可以有这样的方法,它会做你的POST请求:

public class Credentials
{
    [JsonProperty("agent")]
    public Agent Agent { get; set; }

    [JsonProperty("username")]
    public string Username { get; set; }

    [JsonProperty("password")]
    public string Password { get; set; }

    [JsonProperty("token")]
    public string Token { get; set; }
}

public class Agent
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("version")]
    public int Version { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • 您不应该在同步CPU绑定方法上使用Task.Run,​​因为您只是在没有任何好处的情况下启动新线程! (11认同)
  • 旁注:请勿将HttpClient使用using。参见:https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ (4认同)
  • 完美,但是什么是等待Task.run(()? (3认同)
  • 您不必为每个属性都输入 `JsonProperty`。只需使用 Json.Net 内置的 [CamelCasePropertyNamesContractResolver](https://www.newtonsoft.com/json/help/html/ContractResolver.htm) 或 [自定义`NamingStrategy`](https://stackoverflow.com/a/ 47839347/3312114)自定义序列化流程 (3认同)
  • 使用System.Net.Http.Formatting,您可以定义扩展方法:“ await httpClient.PostAsJsonAsync(” api / v1 / domain“,csObjRequest)” (3认同)

Jan*_*jsi 6

您可以HttpContent结合使用JObject规避和来构建自己JProperty,然后ToString()在构建时调用它StringContent

        /*{
          "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);
            }
        }
Run Code Online (Sandbox Code Playgroud)


The*_*le1 6

使用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);

// ...
Run Code Online (Sandbox Code Playgroud)


Ruk*_*ghe 5

您还可以使用 HttpClient() 中可用的 PostAsJsonAsync() 方法

   var requestObj= JsonConvert.SerializeObject(obj);
   HttpResponseMessage response = await    client.PostAsJsonAsync($"endpoint",requestObj).ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,自 .NET4.5 左右以来,“HttpClient”上没有“PostAsJsonAsync()” (3认同)