locked
Problem accessing API RRS feed

  • Question

  • User-1165400470 posted

    Hi

    I have an API controller as below at the end. When I POST to it from swagger it works fine. Image below. However when I post using this code then it fails. 

            public async Task<string> authenticate(string username, string password, string deviceId)
            {
                url = "http://blah-blah/token";
                username = "username";
                password = "password";
    
                CreateTokenViewModel testmodel = new CreateTokenViewModel { Username = username, Password = password };
                var client = new HttpClient();
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                HttpContent senddatacontent = new StringContent(JsonConvert.SerializeObject(testmodel), Encoding.UTF8, "application/json");
                HttpResponseMessage response = await client.PostAsync(url, senddatacontent);
    
                var jsonContent = await response.Content.ReadAsStringAsync();
            }
    
        public class CreateTokenViewModel
        {
            public string Username { get; set; }
    
            public string Password { get; set; }
        }

    What is the problem if its easy if its easy to see, or how can I debug it from here?

    Thanks

    Regards

    swagger-token

        [RoutePrefix("v2.0/token")]
        public class TokenController : ApiController
        {
            [HttpPost]
            [Route("create", Name = "AdminGetToken")]
            public async Task<IHttpActionResult> Get([FromBody]CreateTokenViewModel model)
            {
                string baseAddress = Request.RequestUri.GetLeftPart(UriPartial.Authority) + "/";
    
                string grant_type = "password";
                string userName = model.Username;
                string password = model.Password;
    
                var client = new HttpClient();
                var tokenResponse = await client.PostAsync(baseAddress + "token", new FormUrlEncodedContent(form));
    
                var jsonContent = await tokenResponse.Content.ReadAsStringAsync();
    
                Token token = JsonConvert.DeserializeObject<Token>(jsonContent);
                client.Dispose();
                return Ok(token.AccessToken);
            }
    
            public class Token
            {
                [JsonProperty("access_token")]
                public string AccessToken { get; set; }
    
                [JsonProperty("token_type")]
                public string TokenType { get; set; }
    
                [JsonProperty("expires_in")]
                public int ExpiresIn { get; set; }
    
                [JsonProperty("refresh_token")]
                public string RefreshToken { get; set; }
            }
    
        }

    Friday, August 21, 2020 2:23 AM

Answers

  • User303363814 posted

    Just some random stuff I noticed...

    unsupported_grant_type - so, where do you set grant_type?  What is it set to?  What are the supported values?

    POST 2.0/token/create seems to then do a POST to 2.0/token with a body that is an encoded form of a variable which does not exist ('form')

    The screenshot from Swagger seems to POST to 2.0/token/create but authenticate seems to post to /token  (no '2.0' and no 'create') - but you don't show the code for /token

    The method which handles the POST 2.0/token/create (confusing called 'Get') seems to set a variable called 'grant_type' and then not use it. (as well as variables called 'username' and 'password')

    authenticate doesn't seem to add anything called grant_type to the body. (But then again, neither does Swagger)

    Where does the debugger tell you the error comes from?  I'm guessing that it is from the method you do not show 2.0/token

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, August 21, 2020 8:43 AM
  • User303363814 posted

    As it works
    Part of the problem might be the definition of 'it' - from Swagger you invoke 

    2.0/token/create

    from code a totally different end point

    token

    Tip = Error messages are useful.  If it says your 'grant_type' is unsupported then I would be making doubly sure that my 'grant_type' is set to a supported value (I can't see that you ever set it to anything!)

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, August 21, 2020 9:08 AM

All replies

  • User303363814 posted

    then it fails
    Can you expand on this a little?  What does 'fail' mean?  Exception in sender?  No request is sent?  No request is received?  Request received is not in the expected format?  Processing of Request fails? Exception when processing request?  Result of Request is not correct?  Response received is not as expected?  Processing of Response fails?  Wrong result returned after processing Response?  Something else?

    Friday, August 21, 2020 8:02 AM
  • User-1165400470 posted

    Hi Paul

    The service returns unsupported_grant_type. 

    In the calling method authenticate, jsonContent is set to {"error":"unsupported_grant_type"}.

    Thanks

    Regards

    Friday, August 21, 2020 8:07 AM
  • User303363814 posted

    Just some random stuff I noticed...

    unsupported_grant_type - so, where do you set grant_type?  What is it set to?  What are the supported values?

    POST 2.0/token/create seems to then do a POST to 2.0/token with a body that is an encoded form of a variable which does not exist ('form')

    The screenshot from Swagger seems to POST to 2.0/token/create but authenticate seems to post to /token  (no '2.0' and no 'create') - but you don't show the code for /token

    The method which handles the POST 2.0/token/create (confusing called 'Get') seems to set a variable called 'grant_type' and then not use it. (as well as variables called 'username' and 'password')

    authenticate doesn't seem to add anything called grant_type to the body. (But then again, neither does Swagger)

    Where does the debugger tell you the error comes from?  I'm guessing that it is from the method you do not show 2.0/token

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, August 21, 2020 8:43 AM
  • User-1165400470 posted

    Hi Paul

    As it works from swagger my suspicion is its the way Username and Password are packaged into the request in authenticate method that is the issue. I will investigate bit more and come back with findings.

    Regards

    Friday, August 21, 2020 8:54 AM
  • User303363814 posted

    As it works
    Part of the problem might be the definition of 'it' - from Swagger you invoke 

    2.0/token/create

    from code a totally different end point

    token

    Tip = Error messages are useful.  If it says your 'grant_type' is unsupported then I would be making doubly sure that my 'grant_type' is set to a supported value (I can't see that you ever set it to anything!)

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, August 21, 2020 9:08 AM
  • User1686398519 posted

    Hi yahya01,

    var tokenResponse = await client.PostAsync(baseAddress + "token", new FormUrlEncodedContent(form));

    • I want to confirm with you, what is a form? Is it like the following?
    var form = new[]
    {
        new KeyValuePair<string, string>("password", password)
    };
    • It seems that you have requested another api. Can you give its code?

    Best Regards,

    YihuiSun

    Friday, August 21, 2020 9:14 AM
  • User-1165400470 posted

    Hi

    Sorry, code was left out during copy/paste. Here is it in full with missing code in italics. Thanks.

    Regards

       [RoutePrefix("v2.0/token")]
        public class TokenController : ApiController
        {
            [HttpPost]
            [Route("create", Name = "AdminGetToken")]
            public async Task<IHttpActionResult> Get([FromBody]CreateTokenViewModel model)
            {
                string baseAddress = Request.RequestUri.GetLeftPart(UriPartial.Authority) + "/";
    
                string grant_type = "password";
                string userName = model.Username;
                string password = model.Password;
    
                var form = new Dictionary<string, string>
                    {
                        {"grant_type", grant_type},
                        {"username", userName},
                        {"password", password}
                    };
    
                var client = new HttpClient();
                var tokenResponse = await client.PostAsync(baseAddress + "token", new FormUrlEncodedContent(form));
    
                var jsonContent = await tokenResponse.Content.ReadAsStringAsync();
    
                Token token = JsonConvert.DeserializeObject<Token>(jsonContent);
                client.Dispose();
                return Ok(token.AccessToken);
            }
         }
     

    Friday, August 21, 2020 11:01 AM
  • User-474980206 posted

    If you check the your generated json, the properties  probably start with uppercase instead of the required lowercase. Make the property names match in the  class or use the prop name attribute.

    Friday, August 21, 2020 2:32 PM