我正在编写一个Nancy端点,我想做一些我认为应该非常简单的事情。我想支持以json或xml返回内容,但当html或任何其他类型被请求返回406时,不支持。我可以很容易地只强制使用XML或JSON,我想我可以这样做,如果(accept is html)返回406,但我认为在内容协商支持中对此有一些支持。
有人能透露些什么吗?
实现您自己的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; }
}
我们避免使用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");
});
}
}