【问题标题】:ASP.NET Core - Value cannot be null. (Parameter 's') in Current User ProfileASP.NET Core - 值不能为空。当前用户配置文件中的(参数“s”)
【发布时间】:2022-01-22 09:47:11
【问题描述】:

在 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 上进行测试时,我没有得到当前登录用户的个人资料,而是得到了这个错误消息:

值不能为空。 (参数's')

当我尝试调试代码时:

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

给出空值。

为什么会出现这个错误?

那么当前用户存在,因为我能够登录并生成 Bearer JWT Token

【问题讨论】:

    标签: c# asp.net-core postman


    【解决方案1】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 2021-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      相关资源
      最近更新 更多