Reading HttpResponseMessage.Content throws Newtonsoft.Json.JsonReaderException when reading webapi 2 token

15,342

Solution 1

After some intense googling I got my code working.

First thing I did was added an extra class to store the token.

class TokenResponseModel
{
    [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("userName")]
    public string Username { get; set; }

    [JsonProperty(".issued")]
    public string IssuedAt { get; set; }

    [JsonProperty(".expires")]
    public string ExpiresAt { get; set; }
}

After that I changed my code to the following code.

static internal async Task<TokenResponseModel> GetBearerToken(string siteUrl, string Username, string Password)
{
    HttpClient client = new HttpClient();
    client.BaseAddress = new Uri(siteUrl);
    client.DefaultRequestHeaders.Accept.Clear();

    HttpContent requestContent = new StringContent("grant_type=password&username=" + Username + "&password=" + Password, Encoding.UTF8, "application/x-www-form-urlencoded");

    HttpResponseMessage responseMessage = await client.PostAsync("Token", requestContent);

    if (responseMessage.IsSuccessStatusCode)
    {
        string jsonMessage;
        using (Stream responseStream = await responseMessage.Content.ReadAsStreamAsync())
        {
            jsonMessage = new StreamReader(responseStream).ReadToEnd();
        }

        TokenResponseModel tokenResponse = (TokenResponseModel)JsonConvert.DeserializeObject(jsonMessage, typeof(TokenResponseModel));

        return tokenResponse;
    }
    else
    {
        return null;
    }
}

I can now get the bearer token from a WebAPI 2 site in my client so I can add it to future request. I hope it is helpful to someone else.

Solution 2

Another way to do it is:

TokenResponseModel tokenResponse = await response.Content.ReadAsAsync<TokenResponseModel>();
Share:
15,342
Sander Obdeijn
Author by

Sander Obdeijn

Updated on July 03, 2022

Comments

  • Sander Obdeijn
    Sander Obdeijn almost 2 years

    Hi I have writen a piece of code that should login into a WebAPI 2 site from a c# desktop application everything seams to work but I get an Newtonsoft.Json.JsonReaderException with the message as follows

    Error reading string. Unexpected token: StartObject. Path '', line 1, position 1.

    My code is as follows.

    static internal async Task<string> GetBearerToken(string siteUrl, string Username, string Password)
    {
      HttpClient client = new HttpClient();
      client.BaseAddress = new Uri(siteUrl);
      client.DefaultRequestHeaders.Accept.Clear();
    
      HttpContent content = new StringContent("grant_type=password&username=" + Username + "&password=" + Password, Encoding.UTF8, "application/x-www-form-urlencoded");
    
      Task<HttpResponseMessage> responseTask = client.PostAsync("Token", content);
      HttpResponseMessage response = await responseTask;
    
      if (response.IsSuccessStatusCode)
      {
         Task<string> message = response.Content.ReadAsAsync<string>();
    
         return await message;
      }
      else
      {
         return null;
      }
    }
    

    The raw reponse message as reported by fiddler

    HTTP/1.1 200 OK
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Length: 593
    Content-Type: application/json;charset=UTF-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    Set-Cookie: .AspNet.Cookies=vo5b0v_43BLYlfz-rYTZ-TSGi9Rg5jSd9bvKn9693e-Kx3mMI1JVX1Sk-696f_fnPEFPRwFrNWvdMfDWUTWBElfQF3UfcUAxEE5aU5zRgI40sYKapXXnC2ucIiNKCqVsceve0cxNQYVAIr_YhMNjFLRqBX7H3BTPVKGist2AeUkWw6S4VNijx5iQhvWrAvF4xlJSznCiykNqR-QHD_ZLM5-H3GZoghrkvMpr27eXY4mLIqg4lwV2Qah0gQlXnjuWbHHZqLj5HcID1S7_OfPldBE3YqBOR2JxHLITg3yPw3lbXNkHc1UDdG9HExq0faJptz0SBqd8tIeZ7buoJTZ4LHV0TcYSEs4HZ3-Bd84XX7XeWPa5qnTaAJqXaW2FAigD38a9ASr15r5wnzWv9xQxlg; path=/; HttpOnly
    X-SourceFiles: =?UTF-8?B?RDpcMDYgUHJvamVjdEphZGVcMDIgU2FuZGJveFwwNCBDbGVhbnVwIEFQSSBBY2NvdW50XENsZWFudXBBUElBY2NvdW50XFRva2Vu?=
    X-Powered-By: ASP.NET
    Date: Sun, 02 Mar 2014 15:22:57 GMT
    
    {"access_token":"hM_60CprAm6DqCe7qgte1vsnih2d4j1Uy_FDlgoPkEgS_4u0__4lk5KNd0XysTktOfwMw4ffH3uaRmNaFObVnEY3yWS70hio03azUbCrFKk0VNgj31Y0_zLrd-J0ScZ4vzLdtw7KAXtNfcYySKk1EFtJRB4yYcqvobwORC3eu1VHyYInqy7kBgIhAZYE_NZ3zQrrGerZjy__zCuDdRtXO-klkFtg3dONq7cMP_TBi6xLmBjhXlhzUTKGzOrofijlkyMNHF1rx0CgWjhqEx2rJU8Hakq4Bac1pCqoLaYm91DRSrYO--ff4GWlP5wLeqZAhHIA7t17e2pyZXrUT7V1ExBeCnGkWbWoR8Y-QN8ocT7Q3xjydFd4uWSQD5B-Z1bC-nLpUrtkOGZiukl6J3aCJOqeidY6MEM4TMaJZlIp-Oc","token_type":"bearer","expires_in":1209599,"userName":"Alice",".issued":"Sun, 02 Mar 2014 15:22:57 GMT",".expires":"Sun, 16 Mar 2014 15:22:57 GMT"}
    

    I suspect the json parser expects a different message format then it is getting. I don't want the change the webapi site so I probably have to change the client implementation. I don't what I have to change or where i have to look.

  • Steven Liekens
    Steven Liekens about 5 years
    ReadAsAsync<T> doesn't seem to exist in System.Net.Http.HttpContent, is it an extension method?
  • Peter L
    Peter L almost 4 years
    Microsoft.AspNet.WebApi.Client package contains this legacy approach. Or use JSON deserializing directly instead.