2

我正在写一个 Nancy 端点,我想做一些我认为应该非常简单的事情。我想支持以 json 或 xml 格式返回内容,但是当请求 html 或任何其他类型时返回 406 Not supported。我可以轻松地仅强制使用 XML 或 JSON,我想我可以这样做,如果(接受为 html)返回 406,但我认为在内容协商支持中对此有一些支持。

任何人都可以解释一下吗?

4

2 回答 2

1

实现你自己的 IResponseProcessor,Nancy 将把它捡起来并挂在引擎中。

public sealed class NoJsonOrXmlProcessor : IResponseProcessor
    {
        public ProcessorMatch CanProcess(MediaRange requestedMediaRange, dynamic model, NancyContext context)
        {
            if (requestedMediaRange.Matches("application/json") || requestedMediaRange.Matches("aaplication/xml"))
            {
                //pass on, so the real processors can handle
                return new ProcessorMatch{ModelResult = MatchResult.NoMatch, RequestedContentTypeResult = MatchResult.NoMatch};
            }
            return new ProcessorMatch{ModelResult = MatchResult.ExactMatch, RequestedContentTypeResult = MatchResult.ExactMatch};
        }

        public Response Process(MediaRange requestedMediaRange, dynamic model, NancyContext context)
        {
            return new Response{StatusCode = HttpStatusCode.NotAcceptable};
        }

        public IEnumerable<Tuple<string, MediaRange>> ExtensionMappings { get; private set; }
    }
于 2015-04-02T19:48:54.133 回答
1

我们避免使用ResponseProcessor的全部原因是请求仍在通过我们的身份验证层、域层等一直运行。我们想要一种方法来尽快终止请求。

我们最终做的是在我们自己的内部进行检查Boostrapper

public class Boostrapper : DefaultNancyBootstrapper
{
    protected override void RequestStartup(TinyIoCContainer requestContainer, IPipelines pipelines, NancyContext context)
    {
        base.RequestStartup(requestContainer, pipelines, context);

        pipelines.BeforeRequest += nancyContext =>
        {
            RequestHeaders headers = nancyContext.Request.Headers
            if (!IsAcceptHeadersAllowed(headers.Accept))
            {
                return new Response() {StatusCode = HttpStatusCode.NotAcceptable};
            }
            return null;
         }
    }

    private bool IsAcceptHeadersAllowed(IEnumerable<Tuple<string, decimal>> acceptTypes)
    {
        return acceptTypes.Any(tuple =>
        {
            var accept = new MediaRange(tuple.Item1);
            return accept.Matches("application/json") || accept.Matches("application/xml");
        });
    }
}
于 2016-03-17T17:21:24.113 回答