Search code examples
razorasp.net-coreasp.net-identityasp.net-core-2.0

URL.Page returns null for ASP.Core Identity


I have an ASP.Core application. I have added Identity. I have then customized it I have copied the existing logic to send a verification e-mail to another model that resides in a different directory.

The auto generated scripts created an Areas/Identity directory. Underneath that directory, there is Pages/Account/Manage/Index.cshtml.cs file. The code in this folder uses the same call to generate the confirmation email code. It works fine.

However the custom model returns null when I call the Url.Page. I am not sure why. Below is how I am customizing the Identity in startup.cs

services.AddIdentity<WebUser, WebRole>()
        .AddEntityFrameworkStores<MyIdentityDbContext>()
        .AddDefaultTokenProviders()
        .AddDefaultUI();

This is the place where it breaks when it tries to get the Page location using the existing Identity framework. The Url.Page returns null.

var userId = await _userManager.GetUserIdAsync(user);
var email = await _userManager.GetEmailAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.Page(
                 "/Account/ConfirmEmail",
                 pageHandler: null,
                 values: new { userId = userId, code = code },
                 protocol: Request.Scheme);
await _emailSender.SendEmailAsync(
                email,
                "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

Why does calling the URL.Page from a different model create such a difference? I am guessing I am missing something rudimentary on how routing works but not sure what.


Solution

  • That's due to the fact. The scaffolded identity uses a different area called identity so to call it from a different location, you have to add to the

    values= new {area = "Identity", userId = userId, code = code}
    

    See this link on stackoverflow for more information.