首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >大约404响应缺少内容。

大约404响应缺少内容。
EN

Stack Overflow用户
提问于 2017-10-31 14:37:52
回答 1查看 346关注 0票数 2

我试图从web.api返回自定义错误响应。让它是简单的字符串"Oops!"格式为json。因此,我创建了简单的委托处理程序,它替换了如下所示的错误响应:

代码语言:javascript
复制
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;
    }
}

接下来,我确保这是管道中唯一的一个消息处理程序:

代码语言:javascript
复制
httpConfig.MessageHandlers.Clear();
httpConfig.MessageHandlers.Add(new ErrorMessageHandler());

// Only default route
httpConfig.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

app.UseWebApi(httpConfig); // OWIN self-hosting

控制器也是最简单的:

代码语言:javascript
复制
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<string>。但是为什么这个值稍后会被清除掉呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-31 16:45:07

原因是HttpMessageHandlerAdapter.InvokeCore中的代码(基本上是在UseWebApi中间件中):

代码语言:javascript
复制
response = await _messageInvoker.SendAsync(request, cancellationToken);
// ...
if (IsSoftNotFound(request, response)) {
       callNext = true;
}
else { 
    // ...
}

其中IsSoftNotFound是:

代码语言:javascript
复制
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;
}

因此,基本上在"soft“404的情况下,"soft”意味着没有匹配的路由(并由request.Properties中具有特定密钥的属性指示)--中间件将调用下一个组件。否则-只会发出回应。

对于您的情况,这个IsSoftDelete是正确的(因为确实没有匹配的路由),而下一个组件(没有时间弄清楚这是什么)会清除您的响应内容。

若要“修复”此问题,请在以前的处理程序处理完请求后,使用该键从请求中删除属性:

代码语言:javascript
复制
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;
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47038018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档