调用WebApi时抛出No MediaTypeFormatter错误的原因排查
解决WebApi调用时的「No MediaTypeFormatter...」错误
你遇到的这个错误 No MediaTypeFormatter is available to read an object of type 'string' from content with media type 'text/html',本质是客户端解析响应的方式和服务端返回的内容类型不匹配,咱们拆解下问题根源和解决办法:
问题到底出在哪?
先看你的代码细节:
- 客户端配置:你给HttpClient设置了
Accept: application/json,并且用ReadAsAsync<string>()来解析响应——这个方法依赖HttpClient自带的MediaTypeFormatter,而默认情况下,这些Formatter没法处理text/html类型的内容转成string。 - 服务端响应:
- 当请求成功时,你返回的是带字符串的JSON响应(WebApi会把
"SP Bridged Successful "序列化成JSON格式,Content-Type匹配application/json),这时候客户端能正常解析。 - 但当抛出异常时,
CreateErrorResponse()默认会返回**text/html类型**的错误内容,这就和客户端期望的解析方式不兼容了,直接触发了那个错误。
- 当请求成功时,你返回的是带字符串的JSON响应(WebApi会把
- WebApiConfig的小误区:你给JsonFormatter添加了
text/html的支持,但这是针对服务端输出的(意思是服务端可以用JsonFormatter处理text/html类型的请求),不影响客户端的解析逻辑。
几个可行的解决办法
办法1:直接读取响应原始字符串(最省心)
既然你最终要的就是字符串内容,完全没必要用ReadAsAsync<string>(),换成ReadAsStringAsync()就行——这个方法不依赖Formatter,不管响应是什么类型,直接读取文本:
// 替换原来的readTask代码 var readTask = result.Content.ReadAsStringAsync(); readTask.Wait(); response = result.StatusCode + "|" + readTask.Result;
办法2:给客户端添加text/html的Formatter
如果坚持要用ReadAsAsync<string>(),可以给HttpClient加一个能处理text/html类型的字符串Formatter:
using (var client = new HttpClient()) { // 新增这段代码 client.Formatters.Add(new StringMediaTypeFormatter { SupportedMediaTypes = { MediaTypeHeaderValue.Parse("text/html") } }); // 你的原有代码... ReadConfig(); client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", GenerateAuthenticationToken()); client.BaseAddress = new Uri(ApiBaseUrl); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var responseTask = client.PostAsJsonAsync(ApiActionName + "/" + SPId, SPId); responseTask.Wait(); var result = responseTask.Result; var readTask = result.Content.ReadAsAsync<string>(); readTask.Wait(); response = result.StatusCode + "|" + readTask.Result; }
办法3:让服务端错误响应返回JSON格式
修改WebApi的错误返回逻辑,强制返回application/json类型的错误,这样客户端的Accept: application/json就能匹配上:
catch(Exception ex) { // 替换原来的CreateErrorResponse return Request.CreateResponse(HttpStatusCode.BadRequest, new { Message = ex.Message.ToString() }, MediaTypeHeaderValue.Parse("application/json")); }
内容的提问来源于stack exchange,提问作者Kaishu
相关产品推荐
相关产品推荐

