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
在 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