Pittfall
Pittfall

Reputation: 2851

HttpClient PostAsync returns 500 when getting token

I am trying to figure out what I can do (logging, things to check) before having to read server logs as I don't want to miss something stupid before requesting that.

Here is my code:

const string URL = "https://SomeURL/api/security/";
string urlParameters = string.Format("grant_type=password&username={0}&password={1}", username, password);
StringContent content = new StringContent(urlParameters, Encoding.UTF8, "application/x-www-form-urlencoded");

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;

HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
StringContent content = new StringContent(urlParameters, Encoding.UTF8, "application/x-www-form-urlencoded");

var tokenResponse = client.PostAsync("token", content).Result;

I am a little newer to this so I'm not sure what to check next but have tried the same request using postman and get a response with my token so it looks like I am missing something or maybe formatting something incorrectly?

Upvotes: 1

Views: 1484

Answers (2)

Andrew Hillas
Andrew Hillas

Reputation: 21

I was following an online course, and the code for setting the URL parameters were set like this:

public async Task<AuthenticatedUser> Authenticate(string userName, string password)
    {
        var data = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("grant_type", "password"),
            new KeyValuePair<string, string>("username ", "userName"),
            new KeyValuePair<string, string>("password", "password")
        });

        using (HttpResponseMessage response = await apiClient.PostAsync("/Token", data))
        {
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsAsync<AuthenticatedUser>();
                return result;
            }
            else
            {
                throw new Exception(response.ReasonPhrase);
            }
        }
    }

When testing, found that 500 error was being returned for the PostAsync call. I checked my URL address and parameters and they all looked correct. If I tested in Swagger, then I received a 200 status and token was shown.

Following the link by Thomas Levesque I changed how the data variables were set to :

var data = new FormUrlEncodedContent(new Dictionary<string, string>
        {
            ["grant_type"] = "password",
            ["username"] = username,
            ["password"] = password
        });

Now the response status is 200 and the AuthenticatedUser model is populated correctly. However I couldn't understand why Dictionary seem to work and KeyValuePair didn't. So I created the list and then encoded it:

       var dataList = new[]
        {
            new KeyValuePair<string, string>("grant_type", "password"),
            new KeyValuePair<string, string>("username", username),
            new KeyValuePair<string, string>("password", password)
        };

        var content = new FormUrlEncodedContent(dataList);

        using (HttpResponseMessage response = await apiClient.PostAsync(requestUrl, content))

This also worked. I freely admit that I do not fully understand why.....yet.

Upvotes: 2

Pittfall
Pittfall

Reputation: 2851

I did not URL encode my parameters, here's the fix (probably a better way of doing it).

string urlParameters = string.Format("grant_type=password&username={0}&password={1}", Uri.EscapeDataString(username), Uri.EscapeDataString(password));

Upvotes: 0

Related Questions