'ASP.NET Core Web API - Cannot implicitly convert type 'ServiceResult<AuthResult>' to 'AuthResult'
In my ASP.NET Core-6 Web API, I am using IdentityDbContext. I am developing a User login authentication with response to be displayed after successful login. I have this model:
ApplicationUser
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
[DefaultValue(false)]
public bool? IsAdmin { get; set; }
public ICollection<ApplicationUserRole> UserRoles { get; set; }
}
AuthResult:
public class AuthResult
{
public string AccessToken { get; set; }
public string TokenType { get; set; }
public int ExpiresIn { get; set; }
public string RefreshToken { get; set; }
public UserDto User { get; set; }
public IList<string> Role { get; set; }
}
Result:
public class Result
{
public bool Successful { get; set; }
public string[] Errors { get; set; }
#region Helper Methods
internal Result(bool successful, IEnumerable<string> errors)
{
Successful = successful;
Errors = errors.ToArray();
}
public static Result Success()
{
return new Result(true, System.Array.Empty<string>());
}
public static Result Failure(IEnumerable<string> errors)
{
return new Result(false, errors);
}
#endregion
}
I have this service for trapping error:
public class ServiceResult<T> : ServiceResult
{
public T Data { get; set; }
public ServiceResult(T data)
{
Data = data;
}
public ServiceResult(T data, ServiceError error) : base(error)
{
Data = data;
}
public ServiceResult(ServiceError error) : base(error)
{
}
}
public class ServiceResult
{
public bool Succeswsful => this.Error == null;
public ServiceError Error { get; set; }
public ServiceResult(ServiceError error)
{
if (error == null)
{
error = ServiceError.DefaultError;
}
Error = error;
}
public ServiceResult() { }
#region Helper Methods
public static ServiceResult Failed(ServiceError error)
{
return new ServiceResult(error);
}
public static ServiceResult<T> Failed<T>(ServiceError error)
{
return new ServiceResult<T>(error);
}
public static ServiceResult<T> Failed<T>(T data, ServiceError error)
{
return new ServiceResult<T>(data, error);
}
public static ServiceResult<T> Success<T>(T data)
{
return new ServiceResult<T>(data);
}
#endregion
}
UserDto:
public class UserDto
{
public long Id { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Email { get; set; }
public string UserName { get; set; }
public bool? IsAdmin { get; set; }
}
JwtTokenManager
public interface IJwtTokenManager
{
Task<ServiceResult<AuthResult>> GenerateClaimsTokenAsync(string username, CancellationToken cancellationToken);
}
public async Task<ServiceResult<AuthResult>> GenerateClaimsTokenAsync(string username, CancellationToken cancellationToken)
{
var user = await _userManager.FindByNameAsync(username);
var role = await _userManager.GetRolesAsync(user);
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_jwtSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), // TODO: encrypt user id for added security
new Claim(ClaimTypes.Name, username),
new Claim(JwtRegisteredClaimNames.Sub, username),
new Claim(JwtRegisteredClaimNames.Nbf, new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString()),
new Claim(JwtRegisteredClaimNames.Exp, new DateTimeOffset(DateTime.Now.AddMinutes(5)).ToUnixTimeSeconds().ToString()),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
}),
Expires = DateTime.UtcNow.Add(_jwtSettings.Expiration),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var refreshTokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), // TODO: encrypt user id for added security
new Claim(ClaimTypes.Name, username),
new Claim(JwtRegisteredClaimNames.Iss, _jwtSettings.Issuer),
new Claim(JwtRegisteredClaimNames.Iat, new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString()),
new Claim(JwtRegisteredClaimNames.Nbf, new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString()),
new Claim(JwtRegisteredClaimNames.Exp, new DateTimeOffset(DateTime.Now.AddMinutes(30)).ToUnixTimeSeconds().ToString()),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
}),
Expires = DateTime.UtcNow.Add(_jwtSettings.Expiration),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
// Create JWT tokens
var token = tokenHandler.CreateToken(tokenDescriptor);
var refreshtoken = tokenHandler.CreateToken(refreshTokenDescriptor);
return ServiceResult.Success(new AuthResult
{
AccessToken = tokenHandler.WriteToken(token),
TokenType = "Bearer",
ExpiresIn = _jwtSettings.Expiration.Seconds,
RefreshToken = tokenHandler.WriteToken(refreshtoken),
User = _mapper.Map<UserDto>(user),
Role = role,
});
}
SignInCommandHandler:
using Common.Exceptions;
using MediatR;
public class SignInCommandHandler : IRequestHandler<SignInCommand, AuthResult>
{
private readonly ISignInManager _signInManager;
private readonly IJwtTokenManager _jwtTokenManager;
public SignInCommandHandler(ISignInManager signInManager, IJwtTokenManager jwtTokenManager)
{
_signInManager = signInManager;
_jwtTokenManager = jwtTokenManager;
}
public async Task<AuthResult> Handle(SignInCommand request, CancellationToken cancellationToken)
{
// validate username & password
var result = await _signInManager.PasswordSignInAsync(request.Username, request.Password, false, false);
// Throw exception if credential validation failed
if (!result.Successful)
{
throw new UnauthorizedException("Invalid username or password.");
}
// Generate JWT token response if validation successful
AuthResult response = await _jwtTokenManager.GenerateClaimsTokenAsync(request.Username, cancellationToken);
return response;
}
}
After successful login, the user should get a response as shown below:
{
"status_code": 200,
"message": "Successfully logged In",
"result": {
"AccessToken": "",
"TokenType": "Bearer",
"expires": "2021-12-21T11:17:16Z"
"user": {
"id": 3,
"UserName": "",
"Email": "",
"FirstName": "",
"LastName": "",
},
"role": [
""
],
}
}
But I have this error:
Cannot implicitly convert type 'ServiceResult' to 'AuthResult'
I got this code highlighted:
await _jwtTokenManager.GenerateClaimsTokenAsync(request.Username, cancellationToken)
I changed to:
public class SignInCommandHandler : IRequestHandler<SignInCommand, AuthResult>
{
private readonly ISignInManager _signInManager;
private readonly IJwtTokenManager _jwtTokenManager;
public SignInCommandHandler(ISignInManager signInManager, IJwtTokenManager jwtTokenManager)
{
_signInManager = signInManager;
_jwtTokenManager = jwtTokenManager;
}
public async Task<AuthResult> Handle(SignInCommand request, CancellationToken cancellationToken)
{
// validate username & password
var result = await _signInManager.PasswordSignInAsync(request.Username, request.Password, false, false);
// Throw exception if credential validation failed
if (!result.Successful)
{
throw new UnauthorizedException("Invalid username or password.");
}
// Generate JWT token response if validation successful
ServiceResult<AuthResult> response = await _jwtTokenManager.GenerateClaimsTokenAsync(request.Username, cancellationToken);
return response;
}
}
But still got the same error in the code.
How do I resolve it?
Thanks
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
