首页 > 解决方案 > 使用 Json 对象的 C# HttpClient Post 失败

问题描述

问题陈述:

我正在尝试使用 JSON 数据将数据发布到 C# 中的测试 url 失败,但是当我在 Postman 中尝试相同的事情时它成功了。

C# 代码片段

            string uploadPath = @"https://api.test.com/test";
            string jsonData = "{ \"message\":\"ERROR: ABCDEXY: Price\"," +
            "\"source\":\"BYODB\"," +
            "\"tag\":[\"ABXT\",\"I232-F103\"],\"ID\":\"{76573406E8}\"}";

            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "apiKey " + "7cbafstad-677654c4-8765fgt-95deb");
                var content= new StringContent(jsonData, Encoding.UTF8, "application/json");
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                HttpResponseMessage response = client.PostAsync(uploadPath, content).Result;
                var responseBody = response.Content.ReadAsStringAsync().Result;
                if (response.IsSuccessStatusCode)
                {
                    var sucessRes = JsonConvert.DeserializeObject<dynamic>(responseBody);
                    //Print Success Msg
                }
                else
                {
                    var failureRes = JsonConvert.DeserializeObject<dynamic>(responseBody);
                    //Print Failure Msg
                }
            }

异常详情:

对于响应对象,我收到:

response = {StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Transfer-Encoding: chunked
  Connection: keep-alive
  X-Response-Time: 0.001
  X-Request-ID: 4514d1b-1a3f-4277-9997-2813cd9d28ed
 X-Rat...

对于响应正文,我收到:

{"message":"Invalid JSON","took":0.001,"requestId":"4514d1b-1a3f-4277-9997-2813cd9d28ed"}

当我尝试通过邮递员调用它时,它成功了:

我在 C# JSON Post 中做错了什么?

标签: c#.netjson.nethttpclient

解决方案


最好的方法是使用一个实际的对象,让 NewtonsoftJson 负责序列化。

为此,您将需要两个 nuget 包:

  1. Microsoft.AspNet.WebApi.Client
  2. 牛顿软件.Json

代码如下所示:

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace Custom.ApiClient
{
    internal static class WebApiManager
    {
        //private const string _requestHeaderBearer = "Bearer";
        private const string _responseFormat = "application/json";

        private static readonly HttpClient _client;

        static WebApiManager()
        {

            // Setup the client.
            _client = new HttpClient { BaseAddress = new Uri("api url goes here"), Timeout = new TimeSpan(0, 0, 0, 0, -1) };

            _client.DefaultRequestHeaders.Accept.Clear();
            _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(_responseFormat));

            // Add the API Bearer token identifier for this application.
            //_client.DefaultRequestHeaders.Add(RequestHeaderBearer, ConfigHelper.ApiBearerToken);       
        }
        public static async Task<T> Post<T>(object requestObject)
        {//the request object is the object being sent as instance of a class
            var response = _client.PostAsJsonAsync("api extra path and query params go here", requestObject);

            return await ProcessResponse<T>(response);
        }
        private static async Task<T> ProcessResponse<T>(Task<HttpResponseMessage> responseTask)
        {//T represents the respose you expect from this call
            var httpResponse = await responseTask;

            if(!httpResponse.IsSuccessStatusCode)
                throw new HttpRequestException(httpResponse.ToString());

            var dataResult = await httpResponse.Content.ReadAsAsync<T>();

            return dataResult;
        }
    }
}

要使用此代码,您需要执行以下操作:

var myObject = new Object_I_Want_To_Send();
//set some properties here

var response = await WebApiManager.Post<MyResponse>(myObject);

推荐阅读