I'm encountering an issue when attempting to reset a password in my ASP.NET Core Web API application. Upon navigating to the reset password URL generated by the system, I receive an HTTP ERROR 405. Here's the URL I'm redirected to:http://localhost:5181/api/authentication/reset-password?validEmailToken=CfDJ8AKMVdzkx%2BtOiWaFsbCvrZzc9ONeqD2FnOoZXytsyy5Aa%2FCT67TmjnVr2wiExF2g72BoT0w1IiZWgrtl03WQ9gnVNp698fnpV9ldbS8AU0EBg9qVo8SlRHwOgfEVwTu524K82X1m4SlE4ETp5LhE7839tXyLw%2FrA%2Bj3xYNJLJHfmp3%2FJz7AF%2BVitmYf4mYG%2F37tGNJoaLtwTaZ%2BDMZ%2FXUg0iMP6gGC4COz%2BQ7wv2Hu4w
Additionally, here's the relevant code snippets:
public class EmailService(ISmtpService _smtpService){ public async Task<ErrorOr<Success>> SendResetPasswordEmailAsync( string email, string token, string baseUrl, string userName) { string url = $"{baseUrl}api/authentication/reset-password?email={email}&" + $"validEmailToken={WebUtility.UrlEncode(token)}"; string emailBody = string.Empty; using (StreamReader reader = new("./EmailTemplates/forgot-password.html")) { emailBody = reader.ReadToEnd(); } emailBody = emailBody.Replace("{{ name }}", userName); emailBody = emailBody.Replace("{{ url }}", url); await _smtpService.SendEmailAsync(email, "Reset password", emailBody); return Result.Success; }}public class UserAuthenticationService : IUserAuthenticationService{ private readonly UserManager<UserEntity> _userManager; private readonly SignInManager<UserEntity> _signInManager; private readonly ILogger<ChangeEmailCommandHandler> _logger; public UserAuthenticationService(UserManager<UserEntity> userManager, SignInManager<UserEntity> signInManager, ILogger<ChangeEmailCommandHandler> logger) { _userManager = userManager; _signInManager = signInManager; _logger = logger; } public async Task<string> GeneratePasswordResetTokenAsync(UserEntity user) { var token = await _userManager.GeneratePasswordResetTokenAsync(user); return token; } public async Task<ErrorOr<Success>> ResetPasswordAsync(UserEntity user, string token, string password) { var resetPasswordResult = await _userManager.ResetPasswordAsync(user, token, password); if (resetPasswordResult.Succeeded) { return Result.Success; } else { return Error.Validation(resetPasswordResult.Errors.FirstOrDefault()?.Description.ToString()); } } public async Task<ErrorOr<UserEntity>> ChangePasswordAsync(UserEntity user, string currentPassword, string newPassword) { var changePassword = await _userManager.ChangePasswordAsync(user, currentPassword, newPassword); if (!changePassword.Succeeded) { return Error.Validation(changePassword.Errors.FirstOrDefault()!.Description.ToString()); } return user; }}public class ForgotPasswordQueryHandler : IRequestHandler<ForgotPasswordQuery, ErrorOr<Success>>{ private readonly IUserRepository _userRepository; private readonly IUserAuthenticationService _userAuthenticationService; private readonly EmailService _emailService; private readonly IJwtGenerator _jwtGenerator; public ForgotPasswordQueryHandler(IUserRepository userRepository, IUserAuthenticationService userAuthenticationService, EmailService emailService, IJwtGenerator jwtGenerator) { _userRepository = userRepository; _userAuthenticationService = userAuthenticationService; _emailService = emailService; _jwtGenerator = jwtGenerator; } public async Task<ErrorOr<Success>> Handle(ForgotPasswordQuery request, CancellationToken cancellationToken) { var errorOrUser = await _userRepository.GetByEmailAsync(request.Email); if (errorOrUser.IsError) { return Error.Validation("User with this email doesn't exist"); } var user = errorOrUser.Value; string token = await _userAuthenticationService.GeneratePasswordResetTokenAsync(user); string? userName; if (string.IsNullOrEmpty(user.FirstName) || string.IsNullOrEmpty(user.LastName)) { if (string.IsNullOrEmpty(user.LastName) && string.IsNullOrEmpty(user.FirstName)) { userName = user.Email; } else if (string.IsNullOrEmpty(user.LastName)) { userName = user.FirstName; } else { userName = user.LastName; } } else { userName = user.FirstName +" " + user.LastName; } var sendEmailResult = await _emailService .SendResetPasswordEmailAsync(user.Email!, token, request.BaseUrl, userName); return sendEmailResult; }}[Route("api/[controller]")][ApiController][AllowAnonymous]public class AuthenticationController : ApiController{ private readonly ISender _mediatr; private readonly IMapper _mapper; private readonly IConfiguration _configuration; public AuthenticationController(ISender mediatr, IMapper mapper, IConfiguration configuration) { _mediatr = mediatr; _mapper = mapper; _configuration = configuration; } [HttpGet("forgot-password")] public async Task<IActionResult> ForgotPasswordAsync([FromQuery]String email) { await Console.Out.WriteLineAsync(email); var baseUrl = _configuration.GetRequiredSection("HostSettings:ClientURL").Value; await Console.Out.WriteLineAsync(baseUrl); var query = new ForgotPasswordQuery(email, baseUrl); await Console.Out.WriteLineAsync(query.Email); var forgotPasswordResult = await _mediatr.Send(query); await Console.Out.WriteLineAsync(forgotPasswordResult.ToString()); return forgotPasswordResult.Match( forgotPasswordRes => Ok(forgotPasswordResult.Value), errors => Problem(errors)); }}
However, when I click on the reset password link received in the email, instead of being directed to the password reset page, I'm encountering an HTTP ERROR 405. I've double-checked the code and the URL format, but I'm still unable to identify the root cause of this issue.