You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 18:39:03