0

I am trying to call this API using the async await style but having some issues.

public async Task<User> GetUser(int userId)
{
    User user = null;
    HttpResponseMessage response = await client.GetAsync("/user/...");
    if(response.IsSuccessStatusCode)
    {
        var result = await response.Content.ReadAsStringAsync();
        user = JsonConvert.DeserializeObject<User>(result);
    }

    return user;
}

I am calling the above method in my console app:

var user = apiClient.GetUser(123);

Console.WriteLine($"user result is {user.Result.UserId}");

I get the error:

An unhandled exception of type 'System.NullReferenceException Object reference not set to an instance..

Is my code snippet following the best practise is there something wrong?

My endpoint works fine when I test using Postman.

Update

The interface for my GetUser method is:

Task<User> GetUser(int userId);
slugster
  • 49,403
  • 14
  • 95
  • 145
cool breeze
  • 4,461
  • 5
  • 38
  • 67
  • Can you add the full stack trace where the Null exception occurred? it can help to understand which variable is null – elirandav Jul 04 '17 at 20:42
  • It is on my Console.WriteLine line... – cool breeze Jul 04 '17 at 20:45
  • @VladStryapko I added my interface signature also, I can't seem to be able to add await to the line: ```the await operator can only be used in an async method....``` – cool breeze Jul 04 '17 at 20:49
  • @coolbreeze I've deleted my comment since I saw you were using Result inside the string interpolation so you can avoid awaiting. However, it would be still better to encapsulate all your code inside something like AsyncMain and wait for that. AsyncMain in its turn can be truly async and you can use await inside it. (I assume you're using Console Application project) – Vlad Stryapko Jul 04 '17 at 21:06
  • Could you simply place a breakpoint right at Console.WriteLine and see what result is? Also, for the ease of debugging you can use var user = apiClient.GetUser(123).Result and observe what's inside. – Vlad Stryapko Jul 04 '17 at 21:14
  • Put a breakpoint on this line `return user;`. It is almost certainly null. And that is almost certainly since `response.IsSuccessStatusCode` is false. – mjwills Jul 04 '17 at 22:16
  • There is nothing wrong with your async code. This is just a simple NRE you are encountering here. Debug your code to find out why this happens and fix it then. We can really just make wild guesses here. As mjwills says above, `response.IsSuccessStatusCode` is likely false, so the user value is never actually set. – poke Jul 04 '17 at 22:58

2 Answers2

0

I did the following, I was getting also an error and when I get the value I also get the result response.Content.ReadAsStringAsync().Result;, but also you should debug and check that you are really getting a json value.

    string responseString = "";
    ...
        if (response.IsSuccessStatusCode)
        {
         responseString = response.Content.ReadAsStringAsync().Result;
         Message jsonObject = JsonConvert.DeserializeObject<Message>(responseString.ToString(), 
    new JsonSerializerSettings
    {
    NullValueHandling = NullValueHandling.Ignore
    });

        ...
}    
-1

Best practice to always initialize object.

User user = new User();  // Ensuring it will return a empty object instead of null.

Without seeing the actual full code, it is hard to figure out what is insider GetAsync(...)

William Han
  • 78
  • 1
  • 7
  • While this will certainly get rid of the exception, this is not really a useful solution for the actual problem. Sooner or later, having a default user object will bite you again. You’re just delaying the problem further. And it’s debatable whether an API that’s supposed to find a user should really return an empty user object when said user couldn’t be found. – poke Jul 04 '17 at 23:04