C# 一些404响应缺少内容
我正在尝试从web.api返回自定义错误响应。让它成为简单的字符串C# 一些404响应缺少内容,c#,asp.net-web-api,asp.net-web-api2,owin,delegatinghandler,C#,Asp.net Web Api,Asp.net Web Api2,Owin,Delegatinghandler,我正在尝试从web.api返回自定义错误响应。让它成为简单的字符串“Oops!”格式为json。因此,我创建了一个简单的委托处理程序,它替换了如下错误响应: public class ErrorMessageHandler : DelegatingHandler { protected override async Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, Cancellat
“Oops!”
格式为json。因此,我创建了一个简单的委托处理程序,它替换了如下错误响应:
public class ErrorMessageHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
if (response.IsSuccessStatusCode)
return response;
var formatter = new JsonMediaTypeFormatter();
var errorResponse = request.CreateResponse(response.StatusCode, "Oops!", formatter);
return errorResponse;
}
}
控制器也是最简单的一个:
public class ValuesController : ApiController
{
public IHttpActionResult Get(int id)
{
if (id == 42)
return Ok("Answer to the Ultimate Question of Life, the Universe, and Everything");
return NotFound();
}
}
有趣的是:
给我200个带值字符串的响应/api/values/42
用我的自定义/api/values/13
字符串给我404响应“Oops!”
给了我一个空的404响应/api/values/42/missing
最后一个案例是我的问题。当我在委托处理程序的最后一行设置断点时,我清楚地看到
errorResponse
包含具有正确值的ObjectContent
。但是为什么以后会清除此值呢?原因是中的代码(因此基本上在UseWebApi
中间件中):
其中IsSoftNotFound
为:
private static bool IsSoftNotFound(HttpRequestMessage request, HttpResponseMessage response)
{
if (response.StatusCode == HttpStatusCode.NotFound)
{
bool routingFailure;
if (request.Properties.TryGetValue<bool>(HttpPropertyKeys.NoRouteMatched, out routingFailure)
&& routingFailure)
{
return true;
}
}
return false;
}
那么您确定“/api/values/42/missing”命中了您的处理程序吗?我在我的环境中测试了这一点(虽然与您的环境不同,但仍然如此),对我来说,这个处理程序被完全绕过,响应由IIS提供。可能是路由问题?我必须进行一些阅读,但可能正在执行
DelegatingHandler
,但由于未知路径,下游事件正在挤压响应?看起来,HttpRoutingDispatcher
在自定义处理程序之后运行,如所示。@Evk是的,完全确定。处理程序获取带有HttpError
的响应,该响应声明“未找到此请求的路由数据。”
。然后用新的errorResponse
替换该响应,并返回到管道(我想它应该转到HttpServer
)。也许这是owin的问题?@claylong我也有同样的想法,但快速查看asp.net源代码和海报让我相信dispatcher毕竟是handlersOh我的上帝!我检查了所有东西,包括HttpServer,但问题确实出在owin方面。我将进一步调查他们为何实施这种奇怪的“未发现软”行为。非常感谢@SergeyBerezovskiy如果你发现这个软件是关于什么的,请在这里评论或者添加新的答案,因为我也有兴趣知道。
response = await _messageInvoker.SendAsync(request, cancellationToken);
// ...
if (IsSoftNotFound(request, response)) {
callNext = true;
}
else {
// ...
}
private static bool IsSoftNotFound(HttpRequestMessage request, HttpResponseMessage response)
{
if (response.StatusCode == HttpStatusCode.NotFound)
{
bool routingFailure;
if (request.Properties.TryGetValue<bool>(HttpPropertyKeys.NoRouteMatched, out routingFailure)
&& routingFailure)
{
return true;
}
}
return false;
}
public class ErrorMessageHandler : DelegatingHandler {
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken) {
var response = await base.SendAsync(request, cancellationToken);
if (response.IsSuccessStatusCode)
return response;
// here, can also check if 404
request.Properties.Remove(HttpPropertyKeys.NoRouteMatched);
var formatter = new JsonMediaTypeFormatter();
var errorResponse = request.CreateResponse(response.StatusCode, "Oops!", formatter);
return errorResponse;
}
}