南希:如何模仿Web API普通NotFound响应?

时间:2014-12-09 13:00:49

标签: rest asp.net-web-api2 nancy

在调用

时在Web API中
return NotFound();

它会生成以下回复

HTTP/1.1 404 Not Found
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: ...
X-Powered-By: ASP.NET
Date: Tue, 09 Dec 2014 12:54:42 GMT
Content-Length: 0

在南希,无论我怎么努力,我都无法复制这种行为,我总是得到404绿色怪物页面。

我已经实现了一个新的引导程序清除所有处理器并只添加了JsonProcessor,没有运气。

public class ApiBootstrapper : DefaultNancyBootstrapper
{
    protected override NancyInternalConfiguration InternalConfiguration
    {
        get
        {
            return NancyInternalConfiguration.WithOverrides(c => {
                c.ResponseProcessors.Clear();
                c.ResponseProcessors.Add(typeof(JsonProcessor));
            });
        }
    }
}

我已经实施了IStatusCodeHandler而且没有运气

public class NotFoundStatusCodeHandler : IStatusCodeHandler
{
    public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context)
    {
        return statusCode == HttpStatusCode.NotFound;
    }

    public void Handle(HttpStatusCode statusCode, NancyContext context)
    {
        Tuple<string, string>[] headers = {
            Tuple.Create<string, string>("Cache-Control", "no-cache"),
            Tuple.Create<string, string>("Pragma", "no-cache"),
            Tuple.Create<string, string>("Expires", "-1"),
            Tuple.Create<string, string>("Content-Length", "0")
        };

        context.Response.WithStatusCode(404)
                        .WithHeaders(headers);
    }
}

我真的很感激一些帮助。

2 个答案:

答案 0 :(得分:2)

根据Martin的回答,我搜索了Nancy响应类型,并找到了Nancy.HeadResponse,它返回了一个只有标头的响应,就像Web API一样。所以,最终的代码如下:

public class NotFoundStatusCodeHandler : IStatusCodeHandler
{
    public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context)
    {
        return statusCode == HttpStatusCode.NotFound;
    }

    public void Handle(HttpStatusCode statusCode, NancyContext context)
    {
        Tuple<string, string>[] headers = {
            Tuple.Create<string, string>("Cache-Control", "no-cache"),
            Tuple.Create<string, string>("Pragma", "no-cache"),
            Tuple.Create<string, string>("Expires", "-1"),
            Tuple.Create<string, string>("Content-Length", "0")
        };

        Response response = new Response();

        response.WithStatusCode(statusCode)
                .WithHeaders(headers)
                .WithContentType(string.Empty);

        context.Response = new HeadResponse(response);
    }
}

它生成与Web API完全相同的响应。

我必须要做的另一件事是阻止IIS发送自己的404错误页面,这是Paul Stovell在Martin的回答中提到的博客文章。

在Web.config上添加行

<system.webServer>
  ...
  <httpErrors errorMode="Custom" existingResponse="PassThrough" />
  ...
</system.webServer>

在我不断学习南希时,我可能会找到更好的解决方案。现在,我认为它已经足够好了:-)

答案 1 :(得分:1)

您需要将响应中的内容类型设置为HTML以外的内容,因为它默认为

 Tuple<string, string>[] headers = {
            Tuple.Create<string, string>("Cache-Control", "no-cache"),
            Tuple.Create<string, string>("Pragma", "no-cache"),
            Tuple.Create<string, string>("Expires", "-1"),
            Tuple.Create<string, string>("Content-Length", "0")
        };

            context.Response = new TextResponse(JsonConvert.SerializeObject(headers, Formatting.Indented))
            {
                StatusCode = statusCode,
                ContentType = "application/json"
            };

我还建议阅读这篇优秀博客,其中介绍了如何根据客户目前的要求输出错误。 http://paulstovell.com/blog/consistent-error-handling-with-nancy