C#调用SendGrid Restful API返回400 Bad Request错误求助
问题排查与解决方案
核心错误原因
你代码里的直接错误是混用了PostAsJsonAsync和StringContent:PostAsJsonAsync方法的作用是自动将传入的对象序列化为JSON格式作为请求体,你传入已经封装好的StringContent对象,会导致方法把StringContent实例本身序列化后发送,请求体完全不符合SendGrid的接口要求,所以返回400错误。
CORS头说明
响应里的CORS相关字段是SendGrid服务端全局固定返回的响应头,和你使用C#客户端无关,不属于CORS触发场景,不需要额外处理。
其他潜在问题
- 静态
HttpClient的DefaultRequestHeaders是全局共享的,你每次调用方法都重复添加相同的请求头,多次调用后会出现重复头,也会导致请求异常。 - 异步方法中使用
.Result获取结果容易引发线程死锁,建议统一用await关键字。
修复后的代码示例
方案1:使用PostAsync发送预序列化的JSON(你原注释版本的逻辑基础上调整头添加逻辑即可)
// HttpClient初始化时一次性配置通用头,不要每次请求重复添加 private static HttpClient http_client = new HttpClient() { DefaultRequestHeaders = { Accept = { new MediaTypeWithQualityHeaderValue("*/*") }, Host = "api.sendgrid.com", UserAgent = { new ProductInfoHeaderValue("MyApp", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()) } } }; public static async Task<string> SendGridSendMailRequest(string json, string apiToken) { string result = string.Empty; try { var content = new StringContent(json, Encoding.UTF8, "application/json"); // 每次请求单独设置授权头,避免多线程调用时冲突 using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.sendgrid.com/v3/mail/send"); request.Content = content; request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiToken); HttpResponseMessage response = await http_client.SendAsync(request); if (response.IsSuccessStatusCode) { result = await response.Content.ReadAsStringAsync(); } // 调试时可以打开下方代码,打印服务端返回的具体错误信息 // else // { // var errorContent = await response.Content.ReadAsStringAsync(); // MessageBox.Show(errorContent); // } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } return result; }
方案2:使用PostAsJsonAsync(直接传入邮件对象,不要预序列化)
如果你选择用PostAsJsonAsync,不需要自己提前序列化JSON,直接定义SendGrid邮件的实体类,把实体对象传入方法即可,方法会自动完成序列化:
// 需提前定义匹配SendGrid接口规范的SendGridMail实体类 public static async Task<string> SendGridSendMailRequest(SendGridMail mailObj, string apiToken) { string result = string.Empty; try { http_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiToken); HttpResponseMessage response = await http_client.PostAsJsonAsync("https://api.sendgrid.com/v3/mail/send", mailObj); if (response.IsSuccessStatusCode) { result = await response.Content.ReadAsStringAsync(); } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } return result; }
内容的提问来源于stack exchange,提问作者Ross Kelly
相关产品推荐
相关产品推荐

