Gửi JSON qua POST trong C # và Nhận JSON được trả lại?


86

Đây là lần đầu tiên của tôi bao giờ sử dụng JSON cũng như System.NetWebRequesttrong bất kỳ ứng dụng của tôi. Ứng dụng của tôi phải gửi một tải trọng JSON, tương tự như ứng dụng bên dưới đến máy chủ xác thực:

{
  "agent": {                             
    "name": "Agent Name",                
    "version": 1                                                          
  },
  "username": "Username",                                   
  "password": "User Password",
  "token": "xxxxxx"
}

Để tạo tải trọng này, tôi đã sử dụng JSON.NETthư viện. Làm cách nào để gửi dữ liệu này đến máy chủ xác thực và nhận lại phản hồi JSON của nó? Đây là những gì tôi đã thấy trong một số ví dụ, nhưng không có nội dung 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();

Tuy nhiên, điều này có vẻ như rất nhiều mã được so sánh với việc sử dụng các ngôn ngữ khác mà tôi đã sử dụng trong quá khứ. Tôi đang làm điều này một cách chính xác? Và làm cách nào để lấy lại phản hồi JSON để tôi có thể phân tích cú pháp nó?

Cảm ơn, Elite.

Đã cập nhật mã

// 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();
    }
}

2
Bạn có thể thử WebClient.UploadString(JsonConvert.SerializeObjectobj(yourobj))hoặcHttpClient.PostAsJsonAsync
LB

Câu trả lời:


129

Tôi thấy mình đang sử dụng HttpClient thư viện để truy vấn các API RESTful vì mã rất đơn giản và hoàn toàn không được đồng bộ hóa.

(Chỉnh sửa: Thêm JSON từ câu hỏi cho rõ ràng)

{
  "agent": {                             
    "name": "Agent Name",                
    "version": 1                                                          
  },
  "username": "Username",                                   
  "password": "User Password",
  "token": "xxxxxx"
}

Với hai lớp đại diện cho Cấu trúc JSON mà bạn đã đăng có thể trông giống như sau:

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; }
}

bạn có thể có một phương thức như thế này, phương thức này sẽ thực hiện yêu cầu ĐĂNG của bạn:

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 = await Task.Run(() => 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");

using (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
    }
}

5
hoàn hảo, nhưng điều gì đang chờ đợi Task.run (()?
Hunter Mitchell

21
Bạn không nên sử dụng Task.Run trên các phương thức ràng buộc CPU đồng bộ vì bạn chỉ kích hoạt một luồng mới mà không có lợi ích gì!
Stephen Foster,

2
Bạn không cần phải gõ JsonPropertycho mọi thuộc tính. Chỉ cần sử dụng được xây dựng trong của Json.Net CamelCasePropertyNamesContractResolver hoặc một tùy chỉnhNamingStrategy để tùy chỉnh quá trình tuần tự
Seafish

6
Lưu ý phụ: không sử dụng usingvới HttpClient. Xem: aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
maxshuty

4
Với System.Net.Http.Formatting bạn có các phương thức mở rộng được xác định: "chờ httpClient.PostAsJsonAsync (" api / v1 / domain ", csObjRequest)"
hB0

13

Sử dụng gói JSON.NET NuGet và các loại ẩn danh, bạn có thể đơn giản hóa những gì các áp phích khác đang đề xuất:

// ...

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

// ...

6

Bạn có thể xây dựng HttpContentbằng cách sử dụng kết hợp JObjectđể tránh JPropertyvà sau đó gọi ToString()nó khi xây dựng 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);
            }
        }

Làm thế nào để bạn tránh Exception while executing function. Newtonsoft.Json: Can not add Newtonsoft.Json.Linq.JProperty to Newtonsoft.Json.Linq.JArraysai sót?
Jari Turkia

1
Một cá thể HttpClient không được tạo bằng cách sử dụng cấu trúc. Phiên bản phải được tạo một lần và được sử dụng trong toàn bộ ứng dụng. Điều này là do nó sử dụng nhóm kết nối của riêng nó. Mã của bạn chủ yếu có xu hướng ném SocketException. docs.microsoft.com/en-us/dotnet/api/…
Harun Diluka Heshan

2

Bạn cũng có thể sử dụng phương thức PostAsJsonAsync () có sẵn trong HttpClient ()

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


1
Bạn có thể vui lòng giải thích thêm mã của bạn làm gì và nó giải quyết vấn đề như thế nào không?
Nilambar Sharma

Bạn có thể lấy bất kỳ đối tượng nào bạn muốn đăng và tuần tự hóa nó bằng cách sử dụng SerializeObject (); var obj= new Credentials { Agent = new Agent { Name = "Agent Name", Version = 1 }, Username = "Username", Password = "User Password", Token = "xxxxx" }; Và sau đó, không cần phải chuyển đổi nó thành httpContent, bạn có thể sử dụng PostAsJsonAsync () chuyển URL điểm cuối và chính đối tượng JSON đã chuyển đổi.
Rukshala Weerasinghe
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.