1

Problem Statement:

I'm trying to post the data to the test url in C# using JSON data is failing, but when i try the same thing in Postman it succeeds.

C# Code snippet

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

Exception Details:

For Response Object, i'm receiving:

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...

For Response Body, i'm receiving:

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

When i try to invoke this through postman,it is succeeding:

What i'm doing wrong in my C# JSON Post..?

3
  • 1
    Use a sniffer like wireshark or fiddler. Compare headers first request between c# and postman. Make c# headers look like Postman. The c# default headers are not the same as postman. Commented Jul 28, 2020 at 15:48
  • 2
    The server is absolutely correct: your JSON isn't valid. What you've sent in postman includes backslash-r-backslash-n, but your string includes a carriage return and linefeed in the middle of a value, which isn't valid JSON. Commented Jul 28, 2020 at 15:56
  • 2
    If you change \r\n to \\r\\n it may well fix the problem, but I agree with Janothan Alfaro that it would be better not to try to hand-craft the JSON. Commented Jul 28, 2020 at 15:57

1 Answer 1

3

The best approach is to use an actual object and let NewtonsoftJson take care of the serialization.

You will need two nuget packages for this:

  1. Microsoft.AspNet.WebApi.Client
  2. Newtonsoft.Json

The code looks like this:

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

To use this code you need to do something like this:

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

var response = await WebApiManager.Post<MyResponse>(myObject);
Sign up to request clarification or add additional context in comments.

1 Comment

Agreed. String += was/is bad for xml. Is bad for json as well.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.