Не удалось создать ссылку «passwordResetLink» в asp.net сердечник

#c# #asp.net-mvc #asp.net-core #asp.net-core-mvc #asp.net-core-identity

Вопрос:

Я хочу создать систему забытых паролей в своем приложении (Asp.Net Ядро 2.2). Я успешно сгенерировал токен. но проблема в том, что когда я генерирую passwordResetLink значение, оно равно нулю.

 var passwordResetLink = Url.Action("ResetPassword", "Account",
                    new { email = model.Email, token = token }, Request.Scheme);
 

Я не понимаю, что мое email и token не равно нулю, но почему passwordResetLink равно нулю?

вот мой полный код:-

  [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = await userManager.FindByEmailAsync(model.Email);
                
                if (user != null)
                {
                    // Generate the reset password token
                    var token = await userManager.GeneratePasswordResetTokenAsync(user);
                    
                    var passwordResetLink = Url.Action("ResetPassword", "Account",
                    new { email = model.Email, token = token }, Request.Scheme); //here is the main problem.why it's null?
                  
                     return View("ForgotPasswordConfirmation");
                }

                return View("ForgotPasswordConfirmation");
            }

            return View(model);
        }

 

Файл Startup.cs(службы конфигурации):-

  public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IBraintreeService, BraintreeService>();
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                options.IdleTimeout = TimeSpan.FromMinutes(10);
                //options.Cookie.HttpOnly = true;
                // Make the session cookie essential
                options.Cookie.IsEssential = true;
            });

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            services.AddIdentity<IdentityUser, IdentityRole>()
                .AddDefaultUI(UIFramework.Bootstrap4).AddDefaultTokenProviders()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

 

Вот мой вывод:-

введите описание изображения здесь

Комментарии:

1. Url.Action() вернет значение null, если не сможет найти маршрут, соответствующий заданным параметрам. У вас есть AccountController ResetPassword метод с действием, принимающий email token параметр и?

2. @CodeCaster спасибо за ответ. у меня есть AccountController и метод ResetPassword. также я использовал Area в своем проекте.

3. В какой области находится контролер учетных записей?

4. @CodeCaster, меня зовут Display1

5. Затем используйте new { email = model.Email, token = token , area = "Display1" } .

Ответ №1:

Вы должны создать два таких класса:

 public class ResetPasswordTokenProvider<TUser> : DataProtectorTokenProvider<TUser> where TUser : class
{
    public ResetPasswordTokenProvider(IDataProtectionProvider dataProtectionProvider,
            IOptions<ResetPasswordTokenProviderOptions> options)
            : base(dataProtectionProvider, options)
    {
    }
}
public class ResetPasswordTokenProviderOptions : DataProtectionTokenProviderOptions
{
    public ResetPasswordTokenProviderOptions()
    {
        Name = "ResetPasswordDataProtectorTokenProvider";
        TokenLifespan = TimeSpan.FromDays(1);
    }
}
 

И зарегистрируйте созданный класс у поставщика удостоверений:

 services.AddIdentity<IdentityUser, IdentityRole>(identityOptions =>
            {
                identityOptions.Tokens.ProviderMap.Add("ResetPassword",
                    new TokenProviderDescriptor(typeof(ResetPasswordTokenProvider<IdentityUser>)));
                identityOptions.Tokens.PasswordResetTokenProvider = "ResetPassword";
            })
            .AddTokenProvider<ResetPasswordTokenProvider<IdentityUser>>("ResetPassword")
            .AddEntityFrameworkStores<ApplicationDbContext>();
 

Ответ №2:

Вы можете попробовать этот альтернативный способ.

 public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
{

  var code = await userManager.GeneratePasswordResetTokenAsync(user);
  code = System.Web.HttpUtility.UrlEncode(code);
  var token = code;
  var datUrl = "https://localhost:xxxx/Customer/Account/ResetPassword?"   "email="   
  model.Email   "amp;token="   token;

  ....

 

Это решит вашу проблему.

Комментарии:

1. Давайте не будем жестко кодировать URL-адреса и называть это решением проблемы.

2. @CodeCaster, И именно поэтому я уже сказал, что этот ответ был альтернативой. просто посмотрите выше.

3. Только это не так. Он не поддается ремонту и сломается раньше, чем позже.

4. «Моя машина не заводится» — «В качестве альтернативы, вы могли бы попробовать ее подтолкнуть»