ASP.NET 核心 - 值不能为空。当前用户配置文件中的(参数 's')

ASP.NET Core - Value cannot be null. (Parameter 's') in Current User Profile

在 ASP.NET Core Web API 中,我有三个项目:

API.Infrastructure(for DB) -> API.Core(for DTO, Services) -> API.Web

我正在使用 IdentityDbContext。我有一个名为 Profile 的用户配置文件模型。

型号:

namespace API.Infrastructure.Entities.Models
{
    public class Employee
    {
        public long Id { get; set; }
        public string StaffNumber { get; set; }
        public long? UserId { get; set; }
        public DateTime EmploymentDate { get; set; }
        public virtual ApplicationUser User { get; set; }
    }
}

映射器:

public class EmployeeMapperProfile : Profile
{
    public EmployeeMapperProfile()
    {
        CreateMap<Employee, EmployeeProfileDto>();
    }
}

DTO:

namespace Core.DTOs.Empployee.Response
{
    public class EmployeeListDto
    {
        public string StaffNumber { get; set; }
        public DateTime? EmploymentDate { get; set; }
    }
}

public class GenericResponseDto<T>
{
    public int? StatusCode { get; set; }
    public T Result { get; set; }
    public ErrorResponseDto Error { get; set; }
}

我为此创建了一个服务:

namespace API.Core.Helpers
{
    public class UserResolverService
    {
        private readonly IHttpContextAccessor _httpContext;
        private readonly UserManager<ApplicationUser> _userManager;

        public UserResolverService(IHttpContextAccessor httpContext, UserManager<ApplicationUser> userManager)
        {
            _httpContext = httpContext;
            _userManager = userManager;
        }
        public string GetUserId()
        {
            var userId = _userManager.GetUserId(_httpContext.HttpContext.User);
            return userId;
        }
    }
}

然后我有员工档案服务:

Task<GenericResponseDto<EmployeeProfileDto>> GetEmployeeProfileAsync();

public class EmployeeService : I EmployeeService
{
    private readonly HrDbContext _context;
    private readonly IMapper _mapper;
    private readonly UserResolverService _userResolverService;

    public EmployeeService(HrDbContext context, IMapper mapper, UserResolverService userResolverService)
    {
        _mapper = mapper;
        _userResolverService = userResolverService;
    }

    public async Task<GenericResponseDto<EmployeeProfileDto>> GetEmployeeProfileAsync()
    {
        var response = new GenericResponseDto<EmployeeProfileDto>();
        var userId = long.Parse(_userResolverService.GetUserId());
        var employeeId = _context.employees.Where(u => u.UserId == userId).Select(m => m.Id).FirstOrDefault();

        var employeeProfile = await _context.employees.Include(e => e.User)
                                            .FirstOrDefaultAsync(e => e.Id == employeeId);

        if (employeeProfile != null)
        {
            response.Result = _mapper.Map<EmployeeProfileDto>(employeeProfile);
            response.StatusCode = 200;
        }
        else
        {
            response.Error = new ErrorResponseDto()
            {
                ErrorCode = 404,
                Message = "Employee not found!"
            };
            response.StatusCode = 404;

        }
        return response;
    }
}

控制器:

    public async Task<ActionResult<GenericResponseDto<EmployeeProfileDto>>> GetEmployeeProfile()
    {
        var response = await _employeeService.GetEmployeeProfileAsync();
        Response.StatusCode = response.StatusCode ?? StatusCodes.Status200OK;
        return new JsonResult(response);
    }

startup.cs:

 services.AddScoped<IEmployeeService, EmployeeService>();
 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
 services.AddAutoMapper(typeof(EmployeeMapperProfile));

我想使用 id 获取当前登录用户的个人资料。

当我在 POSTMAN 上测试时,我没有获取当前登录用户的配置文件,而是收到此错误消息:

Value cannot be null. (Parameter 's')

当我尝试调试代码时:

var userId = long.Parse(_userResolverService.GetUserId());

给出空值。

为什么会出现此错误?

然后当前用户存在,因为我能够登录并生成 Bearer JWT 令牌

要查找已登录用户的 ID,您可以使用此条件

_httpContext.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value

声明类型可以根据您在创建 jwt 令牌时生成的名称进行更改,以确保您可以获取您的令牌并在 jwt.io 网站上查看其值以查看用户 ID 的密钥并根据此密钥进行更改ClaimTypes.NameIdentifier 对我来说,生成 jwt 时我将其命名为 userId,因此在 httpcontext 中调用它时,我使用以下标准调用它:

_httpContext.HttpContext.User.FindFirst("userId").Value