ServiceStack返回HttpError时响应Content-Type不遵循请求Accept头的问题
ServiceStack返回HttpError时响应Content-Type不遵循请求Accept头的问题
嘿,这个问题我之前排查过,其实是ServiceStack处理HttpError时的默认内容协商逻辑在搞怪~
为什么会出现这种反向匹配的情况?
默认情况下,ServiceStack对HttpError的响应处理有一套预设逻辑:当它检测到请求的Accept头包含text/html时,会优先返回纯文本格式的错误信息(而非渲染HTML错误页面);反之,如果请求的Accept是text/plain,它反而会返回HTML格式的错误页面。这种看似反向的逻辑,是因为框架默认把text/plain请求当成非浏览器的API请求,但内部错误处理的优先级设置导致结果不符合预期。
解决方法有两个,按需选择:
1. 手动指定HttpError的ContentType
最直接的方式就是在返回HttpError时,明确设置响应的内容类型,强制让它遵循你的预期:
public object Delete(MyRequest request) { // Some processing ... var error = new HttpError(HttpStatusCode.BadRequest, "Invalid id"); // 根据请求的Accept头设置对应的Content-Type var acceptHeader = Request.Accept; error.ContentType = acceptHeader.Contains(MimeTypes.Html) ? MimeTypes.Html : MimeTypes.PlainText; return error; }
如果想固定返回某一种格式(比如始终返回纯文本),直接写死即可:
return new HttpError(HttpStatusCode.BadRequest, "Invalid id") { ContentType = MimeTypes.PlainText };
2. 全局配置错误响应的内容协商
如果希望所有错误响应都遵循请求的Accept头,可以在AppHost的Configure方法里全局配置错误处理逻辑:
public override void Configure(Container container) { SetConfig(new HostConfig { // 确保错误响应优先遵循请求的Accept头 ReturnErrorsInJsonFormat = false, // 不强制返回JSON错误 DefaultContentType = MimeTypes.Json // 可选,设置默认内容类型 }); // 或者自定义错误处理Handler,完全控制响应格式 CustomHttpHandlers.Add(HttpStatusCode.BadRequest, new CustomErrorHandler()); } // 自定义错误处理示例 public class CustomErrorHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { var accept = context.Request.AcceptTypes?[0] ?? MimeTypes.PlainText; context.Response.ContentType = accept; context.Response.StatusCode = (int)HttpStatusCode.BadRequest; context.Response.Write("Invalid id"); } public bool IsReusable => true; }
总结
这个问题的核心就是HttpError默认的内容协商逻辑和预期不符,通过手动指定ContentType或者全局配置错误处理,就能轻松解决这个反向匹配的问题啦~
备注:内容来源于stack exchange,提问作者alalalahehehehhahahaha
相关产品推荐
相关产品推荐

