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

如何在C#中发送字符串格式的application/x-www-form-urlencoded请求获取Discord令牌?

解决Discord OAuth2令牌端点的"unsupported_grant_type"错误(C#实现)

问题背景

在JavaScript中通过拼接字符串形式的application/x-www-form-urlencoded请求体,成功从Discord OAuth2令牌端点获取访问令牌,但在C#中使用FormUrlEncodedContent传递参数时,返回{"error": "unsupported_grant_type"}错误——这和之前JS用对象发送请求时的错误完全一致,需要在C#中模拟JS的字符串拼接请求方式。

JavaScript成功代码示例:

var bodyString = `client_id=${clientId}&client_secret=${clientSecret}&grant_type=authorization_code&code=${params['code']}&redirect_uri=https://localhost:4200/callback`;

this.http
  .post('https://discord.com/api/v10/oauth2/token', bodyString, {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
  })
  .subscribe((response) => {
    console.log('response from post', response);
  });

C#解决方案

直接构造与JavaScript完全一致的字符串请求体,使用StringContent设置正确的Content-Type头发送请求,同时对参数值进行URL编码避免特殊字符破坏格式:

1. 构造编码后的请求体字符串

// 对参数值做URL编码,防止特殊字符导致请求格式错误
var bodyString = $"client_id={Uri.EscapeDataString(_discordSettings.ClientId)}" +
                $"&client_secret={Uri.EscapeDataString(_discordSettings.ClientSecret)}" +
                $"&grant_type=authorization_code" +
                $"&code={Uri.EscapeDataString(code)}" +
                $"&redirect_uri={Uri.EscapeDataString(redirectUrl)}";

2. 新增处理字符串格式表单的Post方法

public async Task<T?> PostFormUrlEncodedString<T>(string url, string formBodyString)
{
    var client = _httpClientFactory.CreateClient(_httpClients.ToString());
    // 构造符合要求的请求内容,指定编码和Content-Type
    var content = new StringContent(formBodyString, System.Text.Encoding.UTF8, "application/x-www-form-urlencoded");
    var apiResponse = await client.PostAsync(url, content);
    
    if (!apiResponse.IsSuccessStatusCode)
    {
        return default;
    }
    
    return await apiResponse.Content.ReadFromJsonAsync<T>();
}

3. 调用方法获取令牌

var response = await PostFormUrlEncodedString<DiscordAccessTokenResponse>(_discordSettings.TokenAuthEndpoint, bodyString);

说明

使用FormUrlEncodedContent失败的核心原因是,该类在参数编码、请求头细节上和手动拼接字符串存在细微差异,而Discord的OAuth2端点对请求格式的兼容性要求严格。通过完全模拟JavaScript的请求体格式和编码逻辑,就能解决unsupported_grant_type错误。

内容的提问来源于stack exchange,提问作者muttley91

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:52:53