在C# .NET 6中使用HttpClient发送自定义Content-Type对接Zoopla API时遭遇格式异常求助
解决Zoopla API自定义Content-Type的格式异常问题
我来帮你搞定这个头疼的问题!你遇到的System.FormatException是因为.NET对HTTP头的格式验证很严格,直接把带profile参数的完整Content-Type字符串传进去时,它没法正确解析URL里的特殊字符。
正确的做法:分步构造Content-Type
不要直接把整个application/json;profile=xxx字符串丢给构造函数,而是分开创建媒体类型和参数,让.NET帮你处理格式问题:
// 1. 先创建基础的application/json媒体类型 var mediaType = new MediaTypeHeaderValue("application/json"); // 2. 添加profile参数,传入完整的URL mediaType.Parameters.Add(new NameValueHeaderValue("profile", "http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json")); // 3. 创建请求并设置内容 var request = new HttpRequestMessage(HttpMethod.Post, "https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list") { Content = new StringContent(jsonBody, Encoding.UTF8, mediaType) };
或者你也可以先创建StringContent,再手动设置Content-Type头:
var request = new HttpRequestMessage(HttpMethod.Post, "https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list") { Content = new StringContent(jsonBody, Encoding.UTF8) }; // 单独设置Content-Type及其参数 request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); request.Content.Headers.ContentType.Parameters.Add( new NameValueHeaderValue("profile", "http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json") );
为什么之前的方法会失败?
- 直接在StringContent构造函数传完整字符串:.NET会尝试把整个字符串解析成
MediaTypeHeaderValue,但URL里的://等特殊字符会被当成格式分隔符,导致验证失败。 - 往DefaultRequestHeaders加Content-Type:Content-Type是请求内容的头,属于HttpContent的一部分,不是请求级别的头,放在DefaultRequestHeaders里本身就不符合HTTP规范,而且同样会触发格式验证。
- 用Accept.Add:Accept头是用来告诉服务器你接受什么类型的响应,和发送请求的Content-Type完全是两回事,所以根本不对路。
这样调整之后,构造出来的Content-Type头就完全符合Zoopla API的要求,也能通过.NET的格式验证啦!
内容的提问来源于stack exchange,提问作者user1460473




