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

Xamarin调用Keycloak OAuth2接口返回400 Bad Request问题排查

问题根源

你当前的C#代码存在请求体格式和Content-Type不匹配的错误:

  • 正常运行的JS代码中,jQuery会自动将data对象序列化为application/x-www-form-urlencoded要求的key=value&key2=value2表单格式,和声明的Content-Type一致,所以请求成功。
  • 你的C#代码中将DTO序列化为JSON字符串,却声明Content-Type为application/x-www-form-urlencoded,服务器无法解析请求体,因此返回400错误。

修复方案

C#中发送application/x-www-form-urlencoded格式的请求,需要使用FormUrlEncodedContent类封装请求参数,不要手动序列化JSON:

修复后代码示例

首先假设你的DataDto定义如下:

public class DataDto
{
    public string grant_type { get; set; }
    public string client_id { get; set; }
    public string code { get; set; }
    public string code_verifier { get; set; }
    public string redirect_uri { get; set; }
}

修改HttpPost方法:

private HttpClient _httpClient = new HttpClient();

private async Task<string> HttpPost(string url, DataDto data)
{
    // 将DTO转换为表单键值对集合
    var formParams = new Dictionary<string, string>
    {
        { nameof(data.grant_type), data.grant_type },
        { nameof(data.client_id), data.client_id },
        { nameof(data.code), data.code },
        { nameof(data.code_verifier), data.code_verifier },
        { nameof(data.redirect_uri), data.redirect_uri }
    };

    // 使用FormUrlEncodedContent自动处理格式和Content-Type
    var content = new FormUrlEncodedContent(formParams);
    var response = await _httpClient.PostAsync(url, content);
    
    // 新增响应校验和内容读取逻辑
    response.EnsureSuccessStatusCode();
    return await response.Content.ReadAsStringAsync();
}

其他注意事项

如果参数较多不想手动拼接字典,可以通过反射自动将DTO的所有公共属性转换为键值对集合,无需逐个手动配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 17:15:02