【问题标题】:SendGrid throwing InvalidApiRequestException in sending emailSendGrid 在发送电子邮件时抛出 InvalidApiRequestException
【发布时间】:2026-02-15 21:50:01
【问题描述】:

发送电子邮件时,SendGrid 抛出 InvalidApiRequestException

我正在使用此代码:

public Task SendEmailAsync(string email, string subject, string message)
{
    // Plug in your email service here to send an email.
    var myMessage = new SendGrid.SendGridMessage();
    myMessage.AddTo(email);
    myMessage.From = new MailAddress("varshney@shobhit.com", "Shobhit", System.Text.Encoding.Default);
    myMessage.Subject = subject;
    myMessage.Text = message;
    myMessage.Html = message;
    var credentials = new NetworkCredential(
        Options.SendGridUser,
        Options.SendGridKey);
    // Create a Web transport for sending email.
    var transportWeb = new SendGrid.Web(credentials);
    // Send the email.
    if (transportWeb != null)
    {
        return transportWeb.DeliverAsync(myMessage);
    }
    else
    {
        return Task.FromResult(0);
    }
}

堆栈跟踪是:

InvalidApiRequestException: Bad Request Check `Errors` for a list of errors returned by the API.
SendGrid.ErrorChecker.CheckForErrors(HttpResponseMessage response, Stream stream)
SendGrid.ErrorChecker.<CheckForErrorsAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
SendGrid.Web.<DeliverAsync>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
MessageBoard.Controllers.AccountController.<Register>d__9.MoveNext() in AccountController.cs
                    await _emailSender.SendEmailAsync(model.Email, "Confirm your account",
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
Microsoft.AspNet.Mvc.Controllers.ControllerActionExecutor.<CastToObject>d__8`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker.<InvokeActionAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeActionFilterAsync>d__53.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeAsync>d__44.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNet.Mvc.Infrastructure.MvcRouteHandler.<RouteAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNet.Routing.Template.TemplateRoute.<RouteAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNet.Routing.RouteCollection.<RouteAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNet.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNet.IISPlatformHandler.IISPlatformHandlerMiddleware.<Invoke>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNet.Diagnostics.Entity.MigrationsEndPointMiddleware.<Invoke>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNet.Diagnostics.Entity.DatabaseErrorPageMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNet.Diagnostics.Entity.DatabaseErrorPageMiddleware.<Invoke>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
System.Runtime.CompilerServices.TaskAwaiter.GetResult()
Microsoft.AspNet.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()

【问题讨论】:

  • 当您调用 SendEmailAsync(string email, string subject, string message) 时,您对电子邮件、主题和消息使用什么值?

标签: c# email asp.net-core sendgrid


【解决方案1】:

确保您使用的是 SendGrid C# 库版本 6.3.x 或更高版本。以前的库版本中存在错误。

【讨论】:

    【解决方案2】:

    对于您的凭据,您是否使用了您的 Sendgrid 用户名和密码?还是您的 API 密钥?从您的变量名称看来,您正在传递您的 API 密钥。尝试传递您的密码:

    Options.SendGridUser Options.SendGridPassword

    【讨论】:

    • 我正在使用我的 sendgrid 用户 ID 和密码。
    【解决方案3】:

    我遇到了同样的问题。在我的情况下,根本原因是电子邮件地址中有一些德语字符。要记录确切的错误,请尝试在 try/catch 块下方添加。

                try
                {
                    // Create a Web transport for sending email.
                    var transportWeb = new SendGrid.Web(credentials);
                    // Send the email.
                    if (transportWeb != null)
                    {
                        return transportWeb.DeliverAsync(myMessage);
                    }
                }
                catch (InvalidApiRequestException exception)
                {
                    if (exception.Errors != null)
                    {
                        foreach (var error in exception.Errors)
                        {
                            // Log error
                        }
                    } 
                }
    

    【讨论】:

      【解决方案4】:

      无需任何软件包即可轻松使用 sendgrid API(newtonsoft json 除外)。 在我的示例中,我使用模板;您可以使用内容来注释内容字段

      1) 创建你的类

      public class MailObject
          {
              public ICollection<MailPersonalizations> personalizations { get; set; }
              public Email from { get; set; }
              public string template_id { get; set; }
              //public ICollection<MailContent> content { get; set; }
          }
      
      public class MailPersonalizations
          {
              public ICollection<Email> to { get; set; }
              public string subject { get; set; }
              public Dictionary<string, string> substitutions { get; set; }
          }
      
      public class MailContent
          {
              public string type { get; set; }
              public string value { get; set; }
          }
      
      public class Email
          {
              public string email { get; set; }
              public string name { get; set; }
          }
      

      2) 创建您的 MailObject 并使用 HttpClient 发送它

      public async Task SendEmailAsync(string email, string subject, string message, string url = "", string buttonText = "")
              {
                  //Create a mail object
                  var mailObject = new MailObject {
                      personalizations = new List<MailPersonalizations>(),
                      from = new Email { email = "no-reply@passion4it.be", name = "No-Reply Passion4IT" },
                      template_id = "cc84680c-a569-428b-ab26-9618584bc9ae"
                  };
      
                  //create the mail personalization
                  var personalization = new MailPersonalizations();
                  personalization.to = new List<Email>();
                  personalization.to.Add(new Email { email = email});
                  personalization.subject = subject;
                  //Substitutions
                  personalization.substitutions = new Dictionary<string, string>();
                  personalization.substitutions.Add("-url-", url);
                  personalization.substitutions.Add("-title-", subject);
                  personalization.substitutions.Add("-custtext-", message);
                  personalization.substitutions.Add("-buttonText-", buttonText);
      
                  mailObject.personalizations.Add(personalization); //Adding to the mail object
      
                  //SEND EMAIL USING SENDGRID API
                  using(var client = new HttpClient())
                  {
                      var jsonMail = JsonConvert.SerializeObject(mailObject);//convert object
      
                      client.DefaultRequestHeaders.Accept.Clear(); //Clear headers
                      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //Add Accept type
                      client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "YOUR API KEY"); //Add Authorization
      
                      var response = await client.PostAsync("https://api.sendgrid.com/v3/mail/send", new StringContent(jsonMail, Encoding.UTF8, "application/json")); //Send the mail
                  }
      
                  return; //Closed
              }
      

      【讨论】: