0

I am trying to extract the selected user using an instance of UserManager, in order to display details about a particular user in a view. I am trying to use the following line of code:

var user = await _userManager.Users.SingleOrDefaultAsync(m => m.Id == id);

However, this gives the following error:

"The 'await' operator can only be used within an async method."

I'm really confused, because surely the SingleOrDefaultAsync method is an async method - the clue is in the name! It even says 'awaitable' when I hover my mouse over it, so why can't I use the 'await' keyword in this situation?

I've tried just taking out the 'await' keyword, and it will then compile but if I try to access the View, I get the following error:

InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Threading.Tasks.Task`1[MyProject.Models.ApplicationUser]', but this ViewDataDictionary instance requires a model item of type 'MyProject.Models.ApplicationUser'.

For context, here is my controller method:

    //
    // GET /Account/Details/5
    public IActionResult Details(string id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var user = _userManager.Users.SingleOrDefaultAsync(m => m.Id == id);

        if (user == null)
        {
            return NotFound();
        }

        return View(user);
    }

and here is what my View is expecting:

@model ApplicationUser

Any help is much appreciated, and apologies if this is a very easy thing that I'm struggling on, I'm still very much a beginner with .Net and MVC!

tereško
  • 58,060
  • 25
  • 98
  • 150
Duncs1000
  • 3
  • 2
  • Possible duplicate of [Await operator can only be used within an Async method](https://stackoverflow.com/questions/11836325/await-operator-can-only-be-used-within-an-async-method) – Igor Oct 12 '17 at 19:04

1 Answers1

1

Make your action method async. It should now return Task<IActionResult> instead of IActionResult

Now you can await an async method inside that

public async Task<IActionResult> Details(string id)
{
    if (id == null)
    {
        return NotFound();
    }

    var user = await _userManager.Users.SingleOrDefaultAsync(m => m.Id == id);

    if (user == null)
    {
        return NotFound();
    }
    return View(user);
}

InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Threading.Tasks.Task`1[MyProject.Models.ApplicationUser]', but this ViewDataDictionary instance requires a model item of type 'MyProject.Models.ApplicationUser'

You get the above exception when you call the async method without the await keyword. When you execute the below code,

var user = _userManager.Users.SingleOrDefaultAsync(m => m.Id == id);

Here user is of type Task<User>, not User. But your view is strongly typed to User and expects a User object but you are trying to pass a Task. That is why you are getting the exception.

Shyju
  • 214,206
  • 104
  • 411
  • 497