带有电子邮件确认的ASP.Net WebForms(InvalidApiRequestException错误)

时间:2016-02-02 20:29:09

标签: c# asp.net webforms sendgrid

我尝试使用SendGrid在用户注册后向用户发送确认电子邮件,这样一旦他们点击它,他们的帐户就会被确认,他们可以访问该网站。 我已经按照本教程进行了操作:http://www.asp.net/webforms/overview/security/create-a-secure-aspnet-web-forms-app-with-user-registration-email-confirmation-and-password-reset 甚至已经下载了源代码,一旦我注册用户,仍然会出现错误。确切的错误是:mscorlib.dll中出现“Exceptions.InvalidApiRequestException”类型的异常,但未在用户代码中处理 其他信息:错误请求检查Errors以获取API返回的错误列表。 我今天已经工作了8个小时,我真的迷路了。我将展示相关文件,任何帮助或方向将受到高度赞赏! Register.aspx.cs

public partial class Register : Page
{
    protected void CreateUser_Click(object sender, EventArgs e)
    {
        var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var user = new ApplicationUser() { UserName = Email.Text, Email = Email.Text };
        IdentityResult result = manager.Create(user, Password.Text);
        if (result.Succeeded)
        {
            // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
            string code = manager.GenerateEmailConfirmationToken(user.Id);
            string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request);
            manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>.");

            if (user.EmailConfirmed)
            {
              IdentityHelper.SignIn(manager, user, isPersistent: false);
              IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
            }
            else
            {
              ErrorMessage.Text = "An email has been sent to your account. Please view the email and confirm your account to complete the registration process.";
            }
        }
        else 
        {
            ErrorMessage.Text = result.Errors.FirstOrDefault();
        }
    }
}

在Web.config中的appSetting

<appSettings>
<!-- SendGrid Credentials-->
<add key="emailServiceUserName" value="[mySendGridUsername]" />
<add key="emailServicePassword" value="[MySendGridPassword]" />
<!-- Twilio Credentials-->
<add key="SMSSID" value="[APab1ee340509424be311b64bc673b5885]" />
<add key="SMSAuthToken" value="[5320-5345]" />
<add key="SMSPhoneNumber" value="+[441752414370]" />
</appSettings>

Login.aspx.cs

 public partial class Login : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        RegisterHyperLink.NavigateUrl = "Register";
        // Enable this once you have account confirmation enabled for password reset functionality
        ForgotPasswordHyperLink.NavigateUrl = "Forgot";
        OpenAuthLogin.ReturnUrl = Request.QueryString["ReturnUrl"];
        var returnUrl = HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
        if (!String.IsNullOrEmpty(returnUrl))
        {
            RegisterHyperLink.NavigateUrl += "?ReturnUrl=" + returnUrl;
        }
    }

    protected void LogIn(object sender, EventArgs e)
    {
        if (IsValid)
        {
            // Validate the user password
            var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
            var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();

          // Require the user to have a confirmed email before they can log on.
          var user = manager.FindByName(Email.Text);
          if (user != null)
          {
            if (!user.EmailConfirmed)
            {
              FailureText.Text = "Invalid login attempt. You must have a confirmed email address. Enter your email and password, then press 'Resend Confirmation'.";
              ErrorMessage.Visible = true;
              ResendConfirm.Visible = true;
            }
            else
            {
              // This doen't count login failures towards account lockout
              // To enable password failures to trigger lockout, change to shouldLockout: true
              var result = signinManager.PasswordSignIn(Email.Text, Password.Text, RememberMe.Checked, shouldLockout: false);

              switch (result)
              {
                  case SignInStatus.Success:
                      IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
                      break;
                  case SignInStatus.LockedOut:
                      Response.Redirect("/Account/Lockout");
                      break;
                  case SignInStatus.RequiresVerification:
                      Response.Redirect(String.Format("/Account/TwoFactorAuthenticationSignIn?ReturnUrl={0}&RememberMe={1}", 
                                                      Request.QueryString["ReturnUrl"],
                                                      RememberMe.Checked),
                                        true);
                      break;
                  case SignInStatus.Failure:
                  default:
                      FailureText.Text = "Invalid login attempt";
                      ErrorMessage.Visible = true;
                      break;
                }
            }
          }
       }
    }

    protected void SendEmailConfirmationToken(object sender, EventArgs e)
    {
      var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
      var user = manager.FindByName(Email.Text);
      if (user != null)
      {
        if (!user.EmailConfirmed)
        {
          string code = manager.GenerateEmailConfirmationToken(user.Id);
          string callbackUrl = IdentityHelper.GetUserConfirmationRedirectUrl(code, user.Id, Request);
          manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>.");

          FailureText.Text = "Confirmation email sent. Please view the email and confirm your account.";
          ErrorMessage.Visible = true;
          ResendConfirm.Visible = false;
        }
      }
    }
}   

错误出现在代码行中:

 manager.SendEmail(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>.");

IdentityConfig.cs

  public class EmailService : IIdentityMessageService
{
  public async Task SendAsync(IdentityMessage message)
    {
      await configSendGridasync(message);
    }
  // Use NuGet to install SendGrid (Basic C# client lib) 
  private async Task configSendGridasync(IdentityMessage message)
  {
    var myMessage = new SendGridMessage();
    myMessage.AddTo(message.Destination);
    myMessage.From = new System.Net.Mail.MailAddress(
                        "Royce@contoso.com", "Royce Sellars (Contoso Admin)");
    myMessage.Subject = message.Subject;
    myMessage.Text = message.Body;
    myMessage.Html = message.Body;

    var credentials = new NetworkCredential(
               ConfigurationManager.AppSettings["emailServiceUserName"],
               ConfigurationManager.AppSettings["emailServicePassword"]
               );

    // Create a Web transport for sending email.
    var transportWeb = new Web(credentials);

    // Send the email.
    if (transportWeb != null)
    {
      await transportWeb.DeliverAsync(myMessage);
    }
    else
    {
      Trace.TraceError("Failed to create Web transport.");
      await Task.FromResult(0);
    }
  }
}

public class SmsService : IIdentityMessageService
{
    public Task SendAsync(IdentityMessage message)
    {
      var Twilio = new TwilioRestClient(
         ConfigurationManager.AppSettings["SMSSID"],
         ConfigurationManager.AppSettings["SMSAuthToken"]
     );
      var result = Twilio.SendMessage(
          ConfigurationManager.AppSettings["SMSPhoneNumber"],
         message.Destination, message.Body);

      // Status is one of Queued, Sending, Sent, Failed or null if the number is not valid
      Trace.TraceInformation(result.Status);

      // Twilio doesn't currently have an async API, so return success.
      return Task.FromResult(0);
    }
}

// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };

        // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
        // You can write your own provider and plug it in here.
        manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
        {
            MessageFormat = "Your security code is {0}"
        });
        manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
        {
            Subject = "Security Code",
            BodyFormat = "Your security code is {0}"
        });

        // Configure user lockout defaults
        manager.UserLockoutEnabledByDefault = true;
        manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
        manager.MaxFailedAccessAttemptsBeforeLockout = 5;

        manager.EmailService = new EmailService();
        manager.SmsService = new SmsService();
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
}

public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) :
        base(userManager, authenticationManager) { }

    public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
    {
        return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
    }

    public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
    {
        return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
    }
}

1 个答案:

答案 0 :(得分:1)

在您的web.config文件中,从

更改它
add key="emailServiceUserName" value="[mySendGridUsername]" 
add key="emailServicePassword" value="[MySendGridPassword]" 

到此:

add key="emailServiceUserName" value="mySendGridUsername" 
add key="emailServicePassword" value="MySendGridPassword" 

删除[] s。问题解决了! :)