[英]Getting current logged on user in web api controller
我试图在Web API控制器中检索当前登录的用户详细信息,以创建用户个人资料页面。
我已经创建了方法,但是用户在代码中始终返回null,如下所示。 这在我的MVC控制器中可以正常工作,但在Web API控制器中会引发错误。
[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);
}
}
更新
[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);
}
错误信息:
System.InvalidOperationException:'序列不包含任何元素
我假设您正在使用WebAPI 2。
请尝试以下操作:
var user = _userManager.GetUser(HttpContext.User);
要么
var user = _userManager.FindById(User.Identity.GetUserId());
代替.First()将其更改为.FirstOrDefault()
API是无状态的,这意味着没有登录用户或会话的概念。 这是因为每个请求都是唯一的,独立的,并且包含提供响应所需的所有信息。
API无法知道谁在发送请求,可能有1万个人同时发送请求,那么到底谁在“登录”呢?
因此,如果要加载用户配置文件,则将userID作为参数发送,如下所示:
[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
});
}
}
附带说明一下,如果您没有任何输入参数,或者输入是原始类型(例如string或int),则ModelState.IsValid将不执行任何操作。 仅当您使用正确的规则填充模型类时,才使用ModelState.IsValid。
就我而言,我实际上可以将字符串替换为一个类
public class UserProfileRetrieveModel
{
[Required]
public string UserEmail { get;set; }
}
然后我可以做:
[HttpGet]
public IActionResult userProfile(UserProfileRetrieveModel model)
{
if (ModelState.IsValid)
{
var user = _userManager.Users.First(x => x.Email == model.UserEmail);
//etc
}
else
{
return BadRequest(ModelState);
}
}
---问题更新后
因此看起来您有一个客户端应用程序,并从中调用API。 我上面说的所有内容仍然适用,只需在调用API之前填充您的数据即可。
例:
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;
}
您无需在API中进行任何操作,只需将所需的所有内容从MVC控制器传递给API。
现在,除了所有这些,您还有大量的异步问题。 该部分需要工作,尽管与问题无关。
从错误消息中看来,您正在尝试从空序列中检索元素。 因此,请检查您是否有数据,并尝试使用.FirstOrDefault()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.