使用HttpClient发送PUT请求返回500错误的技术求助
通过某Web服务器的REST API实现多设备间的数据交互,在C#应用中使用HttpClient类发送GET、DELETE、POST请求均正常,但发送携带JSON内容的PUT请求时返回500内部服务器错误。
相关C#代码如下:
public class RegBank { public int Address { get; set; } public int NumRegisters { get; set; } } // static HttpClient obj instantiated at the beginning of the app public static HttpClient httpClient = new HttpClient(); ... // create an object and serialize into JSON string var obj = new RegBank {Address = 0x40, NumRegisters = 123}; string jsonStr = JsonConvert.SerializeObject(obj); // using Newtonsoft.Json library // compose HttpRequestMessage var request = new HttpRequestMessage(HttpMethod.Put, url); request.Headers.TryAddWithoutValidation("X-Auth-Token", "token"); request.Headers.TryAddWithoutValidation("X-Auth-User", "user"); request.Content = new StringContent(jsonStr, Encoding.UTF8, "application/json"); response = await httpClient.SendAsync(request); // yields Error 500
若注释掉request.Content = new StringContent(jsonStr, Encoding.UTF8, "application/json");行,服务器返回400错误,说明服务器正常、鉴权通过但缺少请求数据。相同鉴权和内容条件下的POST请求可正常执行,使用Python发送相同PUT请求也能成功。
请问在配置HttpClient或HttpRequestMessage时我遗漏了什么?
大概率是StringContent构造时默认给Content-Type头附加了charset参数,导致服务器解析PUT请求的JSON时出错。
Python请求库发送JSON时,Content-Type头仅为application/json,但C#中StringContent(jsonStr, Encoding.UTF8, "application/json")会生成application/json; charset=utf-8的头值。部分对HTTP头格式敏感的服务器无法处理这个额外参数,进而返回500错误。
你可以手动修正Content-Type头,移除charset部分:
var content = new StringContent(jsonStr, Encoding.UTF8, "application/json"); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); // 覆盖默认的带charset的头 request.Content = content;
另外,还需要核对C#生成的JSON内容是否和Python发送的完全一致:
- 对比
jsonStr和Python的JSON输出,确保字段名、大小写、数值格式(比如0x40是否被序列化为64而非"0x40")完全匹配 - 确认PUT请求的URL和Python使用的完全相同,没有额外的路径或查询参数差异
如果上述方法无效,可尝试直接使用HttpClient的PutAsJsonAsync方法,它会自动处理JSON序列化和正确的Content-Type头:
var obj = new RegBank {Address = 0x40, NumRegisters = 123}; var request = new HttpRequestMessage(HttpMethod.Put, url); request.Headers.TryAddWithoutValidation("X-Auth-Token", "token"); request.Headers.TryAddWithoutValidation("X-Auth-User", "user"); response = await httpClient.PutAsJsonAsync(url, obj);
内容的提问来源于stack exchange,提问作者Alex0xff

