C# 一些404响应缺少内容

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

我正在尝试从web.api返回自定义错误响应。让它成为简单的字符串
“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();
   }
}
有趣的是:

  • /api/values/42
    给我200个带值字符串的响应
  • /api/values/13
    用我的自定义
    “Oops!”
    字符串给我404响应
  • /api/values/42/missing
    给了我一个空的404响应

最后一个案例是我的问题。当我在委托处理程序的最后一行设置断点时,我清楚地看到
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;
    }
}