Dowlers
Dowlers

Reputation: 1494

HttpClient post returns bad request in c#, works in postman

I'm trying to access a rest endpoint, https://api.planet.com/auth/v1/experimental/public/users/authenticate. It is expecting json in the request body.

I can get the request to work in Postman but not using c#. Using postman I get the expected invalid email or password message but with my code I get "Bad Request" no matter I try.

Here is the code that makes the request

private void Login()
{
    try
    {
        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri("https://api.planet.com/");
        client.DefaultRequestHeaders.Accept.Clear();
        //ClientDefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
        Data.User user = new Data.User
        {
            email = "[email protected]",
            password = "sdosadf"
        };
        var requestMessage = JsonConvert.SerializeObject(user);
        var content = new StringContent(requestMessage, Encoding.UTF8, "application/json");
        var response = client.PostAsync("auth/v1/experimental/public/users/authenticate", content).Result;
        Console.WriteLine(response.ToString());
    }
    catch (WebException wex )
    {
        MessageBox.Show(wex.Message) ;
    }
}
class User
{
    public string email;
    public string password;
}

Here are screen grabs form Postman that are working enter image description here

enter image description here

Upvotes: 2

Views: 7247

Answers (3)

Dowlers
Dowlers

Reputation: 1494

The way to get this to work was to alter the content header "content-type". By default HTTPClient was creating content-type: application/json;characterset= UTF8. I dropped and recreated the content header without the characterset section and it worked.

content.Headers.Remove("Content-Type");
content.Headers.Add("Content-Type", "application/json");

Upvotes: 5

Janu Hassan
Janu Hassan

Reputation: 1

Create a Method Like this...

    static async Task<string> PostURI(Uri u, HttpContent c)
    {            

        var response = string.Empty;
        var msg = "";
        using (var client = new HttpClient())
        {
            HttpResponseMessage result = await client.PostAsync(u, c);
             msg = await result.Content.ReadAsStringAsync();              
            if (result.IsSuccessStatusCode)
            {                   
                response = result.StatusCode.ToString();                    

            }
        } 
        return response;
    }

call In your Method

public void Login()
    {
        string postData ="{\"email\":\"your_email\",\"password\":\"your_password\"}";
        Uri u = new Uri("yoururl");
        var payload = postData;

        HttpContent c = new StringContent(payload, Encoding.UTF8,"application/json");
        var t = Task.Run(() => PostURI(u, c));
        t.Wait();
        Response.Write(t.Result);
    }

Upvotes: 0

Cory Shay
Cory Shay

Reputation: 1234

The issue is you are trying to call an async method without waiting for the response using await method or var task = method; task.Wait() Therefore, when you end up doing response.ToString() it returns the text you are seeing.

One way to handle this within a non-async method would be to do the following:

var task = client.PostAsync("auth/v1/experimental/public/users/authenticate", content);
task.Wait();
var responseTask = task.Content.ReadAsStringAsync();
responseTask.Wait();
Console.WriteLine(responseTask.Result);

Another way is to make the current method async by doing private async void Login() and then do:

var postResp = await client.PostAsync("auth/v1/experimental/public/users/authenticate", content);
var response = await postResp.Content.ReadAsStringAsync();
Console.WriteLine(response);

Upvotes: 1

Related Questions