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
相关产品推荐
相关产品推荐

