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

Time:12-21

In ASP.NET Core Web API, I have three projects:

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

I am using IdentityDbContext. I have a model for the user profile called Profile.

Model:

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; }
    }
}

Mapper:

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; }
}

I created a service for this:

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;
        }
    }
}

Then I have the employee profile service:

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;
    }
}

Controller:

    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));

I want to get the profile of the current logged in user using the id.

When I tested on POSTMAN, instead of getting the profile of the current logged in user I got this ErrorMessage:

Value cannot be null. (Parameter 's')

As I tried to debug the code:

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

gives null.

Why am I getting this error?

Then current user exists, because I was able to login and also generate the Bearer JWT Token

CodePudding user response:

To find id of already loggedin user you can use this criteria

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

Claims type can be changed according to name you are generated when creating jwt token to sure that you can take your token and see its values in jwt.io website to see key of userid and according to this key change ClaimTypes.NameIdentifier for me when generate jwt i named it userId so when calling it in httpcontext i called it with this criteria:

_httpContext.User.FindFirst("userId").Value 
  • Related