Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences between using C# HttpClient API and the postman testing? Client call works on postman, but not C# httpClient getAsync

Enter image description here

Enter image description here

I am testing a REST API post, and it works well when I try it on Postman. However, in some scenario (related to the posting XML data) if I post with HttpClient API, I would receive the following error:

Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

But the same XML content works fine on Postman with status OK and proper response.

What is the differences between using the C# HttpClient API and the postman testing? How can I configure my API call to match with the behavior on postman?

Here I attached the source code, and the Postman screenshot

public void createLoan()
{
    string baseCreateLoanUrl = @"https://serverhost/create?key=";
    var strUCDExport = XDocument.Load(@"C:\CreateLoan_testcase.xml");

    using (var client = new HttpClient())
    {
        var content = new StringContent(strUCDExport.ToString(), Encoding.UTF8, Mediatype);
        string createLoanApi = string.Concat(baseCreateLoanUrl, APIKey);

        try
        {
            var response = client.PostAsync(createLoanApi, content).Result;
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error Happened here...");
            throw;
        }

        if (response.IsSuccessStatusCode)
        {
            // Access variables from the returned JSON object
            string responseString = response.Content.ReadAsStringAsync().Result;
            JObject jObj = JObject.Parse(responseString);

            if (jObj.SelectToken("failure") == null)
            {
                // First get the authToken
                string LoanID = jObj["loanStatus"]["id"].ToString();
                MessageBox.Show("Loan ID: " + LoanID);
            }
            else
            {
                string getTokenErrorMsg = string.Empty;

                JArray errorOjbs = (JArray) jObj["failure"]["errors"];
                foreach (var errorObj in errorOjbs)
                {
                    getTokenErrorMsg += errorObj["message"].ToString() + Environment.NewLine;
                }
                getTokenErrorMsg.Dump();
            }
        }
    }
like image 342
mting923 Avatar asked Dec 13 '16 19:12

mting923


2 Answers

Thanks for Nard's comment, after comparing the header, I found the issue my client header has this: Expect: 100-continue

While postman doesn't has.

Once I removed this by using the ServicePointManager:

ServicePointManager.Expect100Continue = false;

Everything seems fine now. Thanks all the input!

like image 69
mting923 Avatar answered Oct 16 '22 07:10

mting923


My gut tells me it's something simple. First, we know the API works, so I'm thinking it's down to how you are using the HttpClient.

First things first, try as suggested by this SO answer, creating it as a singleton and drop the using statement altogether since the consensus is that HttpClient doesn't need to be disposed:

    private static readonly HttpClient HttpClient = new HttpClient();

I would think it would be either there or an issue with your content encoding line that is causing issues with the API. Is there something you are missing that it doesn't like, I bet there is a difference in the requests in Postman vs here. Maybe try sending it as JSON ala:

     var json = JsonConvert.SerializeObject(strUCDExport.ToString());
     var content = new StringContent(json, Encoding.UTF8, Mediatype);

Maybe the header from Postman vs yours will show something missing, I think the real answer will be there. Have fiddler running in the background, send it via Postman, check it, then run your code and recheck. Pay close attention to all the attribute tags on the header from Postman, the API works so something is missing. Fiddler will tell you.

like image 23
Nard Dog Avatar answered Oct 16 '22 06:10

Nard Dog