繁体   English   中英

在Web API控制器中获取当前登录的用户

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM