【问题标题】:Problem with Email Sender for verification code .net core 2.1验证码 .net core 2.1 的电子邮件发件人问题
【发布时间】:2020-01-07 16:32:13
【问题描述】:

我了解到,通常对于此类错误,您只需在 Startup.cs 上注册新类,如下所示:

services.AddTransient<IEmailSender,MyEmailSender>();

问题是我什至在错误发生之前就实现了它。这是原始错误和代码:

System.InvalidOperationException:尝试激活“xxxx.Areas.Identity.Pages.Account.RegisterModel”时,无法解析“xxxx.Areas.Identity.Services.MyEmailSender”类型的服务。 在 Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp,类型类型,类型 requiredBy,布尔 isDefaultParameterRequired) 在 lambda_method(闭包,IServiceProvider,对象 []) 在 Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelActivatorProvider.c__DisplayClass1_0.b__0(PageContext 上下文) 在 Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.DefaultPageModelFactoryProvider.c__DisplayClass3_0.b__0(PageContext pageContext) 在 Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.CreateInstance() 在 Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeInnerFilterAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext 上下文) 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() 在 Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext) 在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext) 在 Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext) 在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文)

现在是代码:

Startup.cs 我的邮箱注册

        public void ConfigureServices(IServiceCollection services)
        {
            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.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<ApplicationUser, IdentityRole>(config => {
                config.SignIn.RequireConfirmedEmail = true;
                config.Stores.MaxLengthForKeys = 128; })
               .AddEntityFrameworkStores<ApplicationDbContext>()
               .AddDefaultUI()
               .AddDefaultTokenProviders();

            services.AddTransient<IEmailSender, MyEmailSender>(i =>
                new MyEmailSender(
                    Configuration["EmailSender:Host"],
                    Configuration.GetValue<int>("EmailSender:Port"),
                    Configuration.GetValue<bool>("EmailSender:EnableSSL"),
                    Configuration["EmailSender:UserName"],
                    Configuration["EmailSender:Password"]
                )
            );

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddControllersAsServices();
        }    

注册.cshtml.cs

namespace xxxx.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class RegisterModel : PageModel
    {
        private readonly SignInManager<ApplicationUser> _signInManager;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly ILogger<RegisterModel> _logger;
        private readonly MyEmailSender _emailSender;

        public RegisterModel(
            UserManager<ApplicationUser> userManager,
            SignInManager<ApplicationUser> signInManager,
            ILogger<RegisterModel> logger,
            MyEmailSender emailSender)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _logger = logger;
            _emailSender = emailSender;

        }
        [BindProperty]
        public InputModel Input { get; set; }

        public string ReturnUrl { get; set; }

        public class InputModel
        {
            [Required]
            [EmailAddress]
            [Display(Name = "Email")]
            public string Email { get; set; }

            [Required]
            [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
            [DataType(DataType.Password)]
            [Display(Name = "Password")]
            public string Password { get; set; }

            [DataType(DataType.Password)]
            [Display(Name = "Confirm password")]
            [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
            public string ConfirmPassword { get; set; }
            [Required]
            [MinLength(4)]
            [Column(TypeName = "Varchar(30)")]
            public string User { get; set; }
            [Required]
            [MinLength(4)]
            [Column(TypeName = "Varchar(30)")]
            public string Name { get; set; }
            [Required]
            [MinLength(4)]
            [Column(TypeName = "Varchar(30)")]
            public string Surname { get; set; }
            public Gender Gender { get; set; }
            public DateTime RegistrationDate { get; set; } = DateTime.Now;
            [DefaultValue(0)]
            public int Coins { get; set; }
            [Required]
            public bool IsAdmin { get; set; }
        }

        public void OnGet(string returnUrl = null)
        {
            ReturnUrl = returnUrl;
        }

        public async Task<IActionResult> OnPostAsync(string returnUrl = null)
        {
            returnUrl = returnUrl ?? Url.Content("~/");
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser { UserName = Input.User, Email = Input.Email, Name = Input.Name,
                    SurName = Input.Surname, Gender = Input.Gender };
                var result = await _userManager.CreateAsync(user, Input.Password);
                if (result.Succeeded)
                {
                    _logger.LogInformation("User created a new account with password.");

                    var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                    var callbackUrl = Url.Page(
                        "/Account/ConfirmEmail",
                        pageHandler: null,
                        values: new { userId = user.Id, code = code },
                        protocol: Request.Scheme);

                    StringBuilder VerCode = new StringBuilder();
                    Char[] generator = user.Id.ToCharArray();
                    for (int i = 0; i < 16; i = +4)
                    {
                        VerCode.Append(generator[i]);
                    }
                    var verificationCode = VerCode.ToString();
                    await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                        "Your verification code for your registration to Gen/Music is "
                        + verificationCode + " please use this to verify your account!"
                + $"Please write the given code to confirm your account <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>Click here first!</a>.");

                    await _signInManager.SignInAsync(user, isPersistent: false);
                    return LocalRedirect(returnUrl);
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError(string.Empty, error.Description);
                }
            }

            // If we got this far, something failed, redisplay form
            return Page();
        }
    }

}

【问题讨论】:

    标签: c# asp.net .net asp.net-mvc asp.net-core


    【解决方案1】:
    services.AddTransient<IEmailSender, MyEmailSender>();
    

    这一行将IEmailSender 添加到DI 容器中,这意味着对IEmailSender 的任何请求都将通过MyEmailSender 的实例得到满足。它声明类似“每当需要IEmailSender 时,使用MyEmailSender 的实例”。请注意,这不会将 DI 容器配置为满足对 MyEmailSender 的直接请求。

    private readonly MyEmailSender _emailSender;
    
    public RegisterModel(
        UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager,
        ILogger<RegisterModel> logger,
        MyEmailSender emailSender)
    {
        _userManager = userManager;
        _signInManager = signInManager;
        _logger = logger;
        _emailSender = emailSender;
    }
    

    这就是问题所在。切换接口的实现类型,如下所示:

    private readonly IEmailSender _emailSender;
    
    public RegisterModel(
        UserManager<ApplicationUser> userManager,
        SignInManager<ApplicationUser> signInManager,
        ILogger<RegisterModel> logger,
        IEmailSender emailSender)
    {
        _userManager = userManager;
        _signInManager = signInManager;
        _logger = logger;
        _emailSender = emailSender;
    }
    

    这仍将按预期使用您的具体 MyEmailSender 实现。

    【讨论】:

      猜你喜欢
      • 2020-08-07
      • 1970-01-01
      • 2011-04-14
      • 1970-01-01
      • 2018-12-22
      • 2019-06-16
      • 1970-01-01
      • 1970-01-01
      • 2013-07-31
      相关资源
      最近更新 更多