title: Account confirmation and password recovery doesn't want to work using SendGrid
body: <p>There are many tutorials on how to enable account confirmation and password recovery in asp.net, however none of them seem to work for me. I tried using SMTP but that didn't work. I ended up following <a href="http://www.asp.net/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity" rel="nofollow">this</a> tutorial suggested by asp.net. I also didn't find any of the answers on Stackoverflow useful. <br /><br /> 
  I have the following class in <code>IdentifyConfig.cs</code> where "xxxxx" is substituted by my credentials.</p>
  
  <pre><code>    public class EmailService : IIdentityMessageService
      {
          public Task SendAsync(IdentityMessage message)
          {
              return configSendGridasync(message);
          }
  
          private Task configSendGridasync(IdentityMessage message)
          {
              var myMessage = new SendGridMessage();
              myMessage.AddTo(message.Destination);
              myMessage.From = new System.Net.Mail.MailAddress(
                                  "xxxxxx", "xxxxxx");
              myMessage.Subject = message.Subject;
              myMessage.Text = message.Body;
              myMessage.Html = message.Body;
  
              var credentials = new NetworkCredential(
                         ConfigurationManager.AppSettings["xxxxxx"],
                         ConfigurationManager.AppSettings["xxxxxx"]
                         );
  
              // Create a Web transport for sending email.
              var transportWeb = new Web(credentials);
  
              // Send the email.
              if (transportWeb != null)
              {
                  return transportWeb.DeliverAsync(myMessage);
              }
              else
              {
                  return Task.FromResult(0);
              }
          }
      }
  </code></pre>
  
  <p>I have uncommented the code in <code>AccountController.cs</code> to enable email confirmation and password recovery.<br /><code>Register</code> action:</p>
  
  <pre><code>        public async Task&lt;ActionResult&gt; Register(RegisterViewModel model)
          {
              if (ModelState.IsValid)
              {
                  var user = new ApplicationUser { UserName = model.Email, Email = model.Email, UserFirstName = model.UserFirstName, UserSurname = model.UserSurname };
                  var result = await UserManager.CreateAsync(user, model.Password);
                  if (result.Succeeded)
                  {
                      await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
  
                      // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
                      // Send an email with this link
                      string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                      var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                      await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking &lt;a href=\"" + callbackUrl + "\"&gt;here&lt;/a&gt;");
  
                      return RedirectToAction("Index", "Home");
                  }
                  AddErrors(result);
              }
  
              // If we got this far, something failed, redisplay form
              return View(model);
          }
  </code></pre>
  
  <p><code>ForgotPassword</code> action</p>
  
  <pre><code>        public async Task&lt;ActionResult&gt; ForgotPassword(ForgotPasswordViewModel model)
          {
              if (ModelState.IsValid)
              {
                  var user = await UserManager.FindByNameAsync(model.Email);
                  if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
                  {
                      // Don't reveal that the user does not exist or is not confirmed
                      return View("ForgotPasswordConfirmation");
                  }
  
                  // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
                  // Send an email with this link
                  string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
                  var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);      
                  await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking &lt;a href=\"" + callbackUrl + "\"&gt;here&lt;/a&gt;");
                  return RedirectToAction("ForgotPasswordConfirmation", "Account");
              }
  
              // If we got this far, something failed, redisplay form
              return View(model);
          }
  </code></pre>
  
  <p>I have also enabled SSL for my project.<hr />
  When I register a new user it loads for a while then I get the following error:<br /><code>Exceptions.InvalidApiRequestException: Bad Request Check 'Errors' for a list of errors returned by the API.</code><br /><br />The error occurs in <code>await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking &lt;a href=\"" + callbackUrl + "\"&gt;here&lt;/a&gt;");</code> in my <code>Register</code> action found in <code>AccountController.cs</code>.<br /><br />Stack trace:</p>
  
  <pre><code>[InvalidApiRequestException: Bad Request Check `Errors` for a list of errors returned by the API.]
     SendGrid.ErrorChecker.CheckForErrors(HttpResponseMessage response, Stream stream) +566
     SendGrid.&lt;CheckForErrorsAsync&gt;d__0.MoveNext() +429
     System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
     System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
     System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21
     SendGrid.&lt;DeliverAsync&gt;d__0.MoveNext() +641
     System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
     System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
     System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21
     Microsoft.AspNet.Identity.CultureAwaiter.GetResult() +63
     Microsoft.AspNet.Identity.&lt;SendEmailAsync&gt;d__129.MoveNext() +963
     System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
     System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
     System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21
     Splend.Controllers.&lt;Register&gt;d__f.MoveNext() in c:\Users\Bongumusa\Business\Projects\Splend\Splend\Controllers\AccountController.cs:164
     System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
     System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
     System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21
     System.Threading.Tasks.TaskHelpersExtensions.ThrowIfFaulted(Task task) +61
     System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +114
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass37.&lt;BeginInvokeAsynchronousActionMethod&gt;b__36(IAsyncResult asyncResult) +66
     System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +47
     System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +136
     System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +102
     System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +49
     System.Web.Mvc.Async.AsyncInvocationWithFilters.&lt;InvokeActionMethodFilterAsynchronouslyRecursive&gt;b__3d() +117
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass46.&lt;InvokeActionMethodFilterAsynchronouslyRecursive&gt;b__3f() +323
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass33.&lt;BeginInvokeActionMethodWithFilters&gt;b__32(IAsyncResult asyncResult) +44
     System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +47
     System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +136
     System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +102
     System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +50
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass2b.&lt;BeginInvokeAction&gt;b__1c() +72
     System.Web.Mvc.Async.&lt;&gt;c__DisplayClass21.&lt;BeginInvokeAction&gt;b__1e(IAsyncResult asyncResult) +185
     System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +42
     System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +133
     System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56
     System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +40
     System.Web.Mvc.Controller.&lt;BeginExecuteCore&gt;b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +34
     System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70
     System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
     System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
     System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
     System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +44
     System.Web.Mvc.Controller.&lt;BeginExecute&gt;b__15(IAsyncResult asyncResult, Controller controller) +39
     System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +62
     System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
     System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
     System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
     System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +39
     System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +39
     System.Web.Mvc.MvcHandler.&lt;BeginProcessRequest&gt;b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +39
     System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70
     System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
     System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
     System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
     System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +40
     System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
     System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +129
  </code></pre>
  
  <p><br />Quite frankly, I don't understand this stack trace as I am new to asp.net. And as a result, I don't know where to start debugging to trace the problem.<hr /><strong>What seems to be the issue?</strong>   </p>