1

I am trying to access an ASP.NET Web API via c#. I wrote the API and I am able to access it and get a valid response using Postman. The API returns an access_token and refresh_token when presented with a username, password, and grant_type = password.

Here is a screen capture of the response I receive when using Postman:

enter image description here

However, when I try and use the following C# code:

var userToValidate = new UserToValidate
{
    UserName = "johndoe@mydomain.com",
    Password = "Abc123!",
    grant_type = "password"
};

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("http://localhost:4321");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    HttpResponseMessage response = client.PostAsJsonAsync("oauth/token", userToValidate).Result;
    content = response.Content.ReadAsStringAsync().Result;
}

I get an error ... {"error":"unsupported_grant_type"}

I have got to be doing something wrong on the C# side of things. What am I missing?

P.S. Using .Result because debugging async code drives me nuts

webworm
  • 10,587
  • 33
  • 120
  • 217
  • I found the solution in this SO post. http://stackoverflow.com/questions/29246908/c-sharp-unsupported-grant-type-when-calling-web-api. Have to use `application/x-www-form-urlencoded` instead of JSON. – webworm Aug 16 '16 at 21:44
  • Also you can pass PostData as KeyValuePair instead of UserToValidate class `List> postData = new List>(); postData.Add(new KeyValuePair("grant_type", "password")); postData.Add(new KeyValuePair("username", userName)); postData.Add(new KeyValuePair("password", password)); ` – Paresh Aug 17 '16 at 17:16
  • @Paresh - Can you post that up as an answer and I will accept iy. That way there are multiple options. Thanks. – webworm Aug 17 '16 at 17:50

2 Answers2

0

Here is how you can get token using JSON

        using (var client = new HttpClient())
        {
            var email = "xyz"
            var password = "abc";
            var clientId = "123"
            var clientSecret = "456";

            client.BaseAddress = new Uri(baseUrl);

            // We want the response to be JSON.
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            // Build up the data to POST.
            List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();

            postData.Add(new KeyValuePair<string, string>("grant_type",    "password"));
            postData.Add(new KeyValuePair<string, string>("client_id",     clientId));
            postData.Add(new KeyValuePair<string, string>("client_secret", clientSecret));
            postData.Add(new KeyValuePair<string, string>("username",      email));
            postData.Add(new KeyValuePair<string, string>("password",      password));



            // Post to the Server and parse the response.
            HttpResponseMessage response = await client.PostAsJsonAsync("Token", postData);
            string jsonString            = await response.Content.ReadAsStringAsync();
            object responseData          = JsonConvert.DeserializeObject(jsonString);

            // return the Access Token.
            accessToken = ((dynamic)responseData).access_token;
        }

        return accessToken;
Paresh
  • 993
  • 1
  • 7
  • 15
0

The content needs to be urlencoded. This is how it worked for me:

            var httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Add("X-Tenant", xTenant);
            var stringContent = String.Concat("grant_type=password&username=", HttpUtility.UrlEncode(username),
                "&password=", HttpUtility.UrlEncode(password));
            var httpContent = new StringContent(stringContent, Encoding.UTF8, "application/x-www-form-urlencoded");
            var postTask = httpClient.PostAsync(apiLoginUrl, httpContent);
            postTask.Wait();
            var postResult = postTask.Result;
            var content = postResult.Content.ReadAsStringAsync().Result;
            dynamic jsonRes = JsonConvert.DeserializeObject(content);
            string access_token = jsonRes.access_token;
spilafis
  • 88
  • 5