Reputation:
I am trying to retrieve the current logged on user details in a Web API controller to create a user profile page.
I have got the method created but the user keeps returning null in the code was shown below. This works fine in my MVC controller but in Web API controller it throws an error.
[HttpGet]
public IActionResult userProfile()
{
if (ModelState.IsValid)
{
var user = _userManager.Users.First(x => x.Email == User.Identity.Name);
return Ok(new UserViewModel
{
Id = user.Id,
UserName = user.Email,
FirstName = user.FirstName,
LastName = user.LastName
});
}
else
{
return BadRequest(ModelState);
}
}
UPDATE
[HttpGet]
[Authorize(Roles = "Client, Administrator")]
public IActionResult userProfile()
{
string baseUrl = "https://localhost:5001";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(baseUrl);
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(contentType);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", HttpContext.Session.GetString("token"));
UserViewModel userModel = new UserViewModel();
HttpResponseMessage response = client.GetAsync("https://localhost:5001/api/UserAPI").Result;
string stringData = response.Content.ReadAsStringAsync().Result;
userModel = JsonConvert.DeserializeObject<UserViewModel>(stringData);
return View(userModel);
}
Error Message:
System.InvalidOperationException: 'Sequence contains no elements
Upvotes: 0
Views: 3144
Reputation: 6335
An API is stateless meaning that there is no concept of logged in users or sessions. This is because each request is unique, separate and holds all the information required to provide a response.
An API has no way of knowing who is sending a request, there can be 10k people all sending requests at the same time, so who exactly is "logged in"?
So, if you want to load a user profile then send the userID as a parameter, something like:
[HttpGet]
public IActionResult userProfile(string userEmail)
{
if ( !string.IsNullOrEmpty (userEmail) ) ..... etc etc
{
var user = _userManager.Users.First(x => x.Email == userEmail);
return Ok(new UserViewModel
{
Id = user.Id,
UserName = user.Email,
FirstName = user.FirstName,
LastName = user.LastName
});
}
}
As a side note, if you don't have any input parameters or the input is a primitive type such as string or int, then ModelState.IsValid won't do anything. Only use ModelState.IsValid if you have a model class populated with the right rules.
in my case I could actually replace the string with a class
public class UserProfileRetrieveModel
{
[Required]
public string UserEmail { get;set; }
}
then I can do :
[HttpGet]
public IActionResult userProfile(UserProfileRetrieveModel model)
{
if (ModelState.IsValid)
{
var user = _userManager.Users.First(x => x.Email == model.UserEmail);
//etc
}
else
{
return BadRequest(ModelState);
}
}
--- after question updated
so it looks like you have a client application and from that you call the API. everything I said above still applies, simply populate the data you have before calling the API.
Example:
public IActionResult userProfile()
{
//removed code we don't care about
string userEmail = "";// get your user email here in the MVC controller
//populate it in the api url.
//you might need to URL encode it since it will contain dots and @
string apiUrl = "https://localhost:5001/api/UserAPI/{userEmail}";
HttpResponseMessage response = client.GetAsync(apiUrl).Result;
}
you don't need to work out anything in the API, just pass everything you need to the API, from the MVC controller.
Now, all this aside, you have massive async issues. that part needs work although it's not related to the question.
Upvotes: 1
Reputation: 3
From the error message It seems you are trying to retrieve an element from an empty sequence. So check whether you have the the data or not.And also try to use .FirstOrDefault().
Upvotes: 0
Reputation: 1489
Im presuming you're on WebAPI 2.
Try the following:
var user = _userManager.GetUser(HttpContext.User);
or
var user = _userManager.FindById(User.Identity.GetUserId());
Upvotes: 0