0

我在Microsoft.Owin.Host.IIS (Helios) 上运行 Nancy。

我正在尝试连接 conneg viaIResponseProcessor以响应 的Accept标头text/plain,但它只会返回 406。

我尝试了多种内容类型,但没有任何效果....除了,奇怪的是,text/html(在清除基础之后ViewProcessor)。

public class ViewApiProcessor : IResponseProcessor
{
    private readonly IViewFactory viewFactory;

    public ViewApiProcessor(IViewFactory _viewFactory)
    {
        this.viewFactory = _viewFactory;
    }

    private static readonly IEnumerable<Tuple<string, MediaRange>> extensionMappings =
    new[] { new Tuple<string, MediaRange>("txt", MediaRange.FromString("text/plain")) };

    public IEnumerable<Tuple<string, MediaRange>> ExtensionMappings
    {
        get { return extensionMappings; }
    }

    public ProcessorMatch CanProcess(MediaRange requestedMediaRange, dynamic model, NancyContext context)
    {

        bool matchingContentType =
            requestedMediaRange.Matches("text/plain");

        return matchingContentType
            ? new ProcessorMatch { ModelResult = MatchResult.DontCare, RequestedContentTypeResult = MatchResult.ExactMatch }
            : new ProcessorMatch();
    }

    public Response Process(MediaRange requestedMediaRange, dynamic model, NancyContext context)
    {
        context.ViewBag.RequestType = "api";

        var response = (Response)this.viewFactory.RenderView(context.NegotiationContext.ViewName, model, GetViewLocationContext(context));

        return response.WithContentType("text/plain");
    }

    private static ViewLocationContext GetViewLocationContext(NancyContext context)
    {
        return new ViewLocationContext
        {
            Context = context,
            ModuleName = context.NegotiationContext.ModuleName,
            ModulePath = context.NegotiationContext.ModulePath
        };
    }
}

然后,在模块中:

Get["/"] = p => 
{
    return Negotiate.WithView("Index");
};

更新:我已经编辑了上面的代码以显示和的正确IResponseProcessor组合Negotiator

Github 源码

4

2 回答 2

1

这里更有趣的是,你的路线是什么样的?如果你希望它能够协商响应,那么你需要返回一个 `Negotiator`

Get["/"] = _ => {
   return Negotiator.WithModel(...).WithView("foo");
};

如果您返回一个纯文本Response(或任何可以隐式转换为响应的内容,例如字符串、整数、HttpStatusCode 或操作),那么您将完全按照此处的描述规避内容协商https://github.com/NancyFx/Nancy/维基/内容协商

如果您要返回视图,则使用View[..]then 您是说唯一允许的媒体范围是text/html

于 2014-02-28T07:48:00.463 回答
0

Conneg 是寻找问题的解决方案:

HTTP内容协商有四个轴:格式协商(Accept)、字符编码协商(Accept-Charset)、自然语言协商(Accept-Language)和压缩协商(Accept-Encoding)。这些轴需要单独讨论。

  • 按格式协商(接受)

作为 Web 作者,您不能依赖格式协商,因为总有客户接受他们未声明的内容。由于前一点,如果您是浏览器供应商,而另一个供应商发布的浏览器没有声明它支持它支持的东西,那么浪费字节声明它也是没有意义的,因为 Web 作者无论如何都不能(完全)依赖声明。

  • 通过字符编码协商(Accept-Charset)

在主流浏览器中,只有 Chrome 不再发送 Accept-Charset

  • 自然语言协商(Accept-Language)

当网站确实有多种语言版本时,这些版本通常是不相等的。通常,一种语言是网站的主要语言,而其他语言版本不完整、过时或质量低劣。即使每个人都在他们的浏览器中配置了他们的语言偏好,这个人可以阅读的语言组合也会在某些情况下将世界人口划分为相当小的桶,从而使语言组合成为识别特定用户或小群体的方式的用户。由于人们很少配置他们的语言偏好,当有人配置它时,配置很可能成为唯一或几乎唯一的标识。这可以看作是一个隐私问题。

  • 压缩协商(Accept-Encoding)

如今,所有主流浏览器都支持压缩响应。从这个意义上说,该功能是成功的。但是,每个请求最终都包含 23 个字节的样板文件,这是非常浪费的。

参考

于 2016-09-19T21:06:33.843 回答