Reputation: 217
I want to setup a confirm email for new users.
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ConfirmEmail(string userId, string code)
{
if (userId == null || code == null)
{
return RedirectToAction(nameof(HomeController.Index), "Home");
}
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
throw new ApplicationException($"Unable to load user with ID '{userId}'.");
}
var result = await _userManager.ConfirmEmailAsync(user, code);
return View(result.Succeeded ? "ConfirmEmail" : "Error");
}
So when debugging when the link is clicked the userId is ok but the "code" input parameter is null so
if (userId == null || code == null)
is true and then it executes
return RedirectToAction(nameof(HomeController.Index), "Home");
The email that is sent to the registered user is like this :
Please confirm your account by clicking this link: https://localhost:44314/Account/ConfirmEmail?userId=3ec7ac6a-3329-4821-a09b-aa4843598eaa&code=CfDJ8JouO%2BAfPaZIsebmFKKodcE1jEFscFSMcDTvnUPw88tqAKIh0%2BFV6X%2BWCF6fRBgprsymV37RsZsupPoRwCoj8tTT8CckBr0BP9se6DuBxd%2B8fDg2go2S0X9o%2FD9outoU7ShVJl3r3lM5yMXjevtJBoQha9g66ithx%2BhM4Dfskpzt79Imyad6BC0s8s53C7qGZhIx5Dh6DU2KXcVues8XxYQAAhFvzn%2BT49N3ze1%2BihB4Ciwxo5En6sT%2BmbaWvX9N2A%3D%3D'>link
Edit: the link contains & a m p;code instead of &code but it doesen't show in stack overflow
Literally no one has the same problem on the internet so I'm lost here. What am I doing wrong?
public static class UrlHelperExtensions
{
public static string EmailConfirmationLink(this IUrlHelper urlHelper, string userId, string code, string scheme)
{
return urlHelper.Action(
action: nameof(AccountController.ConfirmEmail),
controller: "Account",
values: new { userId, code },
protocol: scheme);
}
public static string ResetPasswordCallbackLink(this IUrlHelper urlHelper, string userId, string code, string scheme)
{
return urlHelper.Action(
action: nameof(AccountController.ResetPassword),
controller: "Account",
values: new { userId, code },
protocol: scheme);
}
}
Update: When I changed & a m p;code to "&code" in the link and pasted it in chrome it worked
Upvotes: 4
Views: 2732
Reputation: 2210
As above this code:
HtmlEncoder.Default.Encode(link)
Is wrong. We are not encoding HTML here. We are encoding an url. One would think that therefore, we should be using url encoding. This:
HttpUtility.UrlEncode(link);
However, it appears that Url.Page is clever enough to encode the parameters automatically. Try the below code:
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = "12345", code =
"567&9", returnUrl = "/index" },
protocol: Request.Scheme);
The result is this:
https://localhost:44383/Identity/Account/ConfirmEmail?userId=12345&code=567%269&returnUrl=%2Findex
As you can see the ampersand in the "code" parameter is being encoded. So the encoding is not necessary and the answer by Jones above is correct.
Upvotes: 1
Reputation: 217
public static Task SendEmailConfirmationAsync(this IEmailSender emailSender, string email, string link)
{
return emailSender.SendEmailAsync(email, "Confirm your email",
$"Please confirm your account by clicking this link: <a href='{HtmlEncoder.Default.Encode(link)}'>link</a>");
}
The problem is here
HtmlEncoder.Default.Encode(link)
just remove it and it works
<a href='{link}'>link</a>
Upvotes: 6