为自托管的WCF服务添加可选的gzip压缩功能

3
如何为我的自托管WCF服务添加可选的gzip压缩?我在此情况下使用WebHttpBinding。我想检查Accept标头是否包含字符串gzip,如果是则压缩内容。
我想使用自定义属性。目前我使用的自定义属性允许我在XML和JSON输出之间进行切换,但我不知道如何压缩输出。
在我的编码器切换属性中,我实现了IDispatchMessageFormatter接口以根据需要更改XmlObjectSerializer。但我不理解如何生成输出以进行修改。
如果有人能指出可能的解决方案,那就太好了。

有趣的问题。为什么它必须是可选的?只是好奇。我认为gzip压缩是几乎所有使用http的设备都支持的标准,因此我的托管WCF服务在IIS配置级别执行它。 - Scen
希望能够更方便地通过 Telnet 测试服务,这样会很好。另外,我不确定第三方客户端是否容易处理压缩。 - rekire
啊,你可能想尝试一下 Fiddler(http://www.fiddler2.com/fiddler2/)来测试你的 WCF http 服务。它非常棒。我还没有遇到过任何不能自动解压缩 gzip 的设备,但我猜我也不能确定所有第三方客户端是否都能处理它。 - Scen
您的问题当然是完全有效的。只是想提醒一下,如果能避免的话,可能会节省您一些时间。 - Scen
1个回答

5
这不是一个属性,而是用于压缩WCF服务响应的基本代码,如果需要,可以将其封装成属性。
public static void CompressResponseStream(HttpContext context = null)
{
    if (context == null)
        context = HttpContext.Current;

    string encodings = context.Request.Headers.Get("Accept-Encoding");

    if (!string.IsNullOrEmpty(encodings))
    {
        encodings = encodings.ToLowerInvariant();

        if (encodings.Contains("deflate"))
        {
            context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
            context.Response.AppendHeader("Content-Encoding", "deflate");
            context.Response.AppendHeader("X-CompressResponseStream", "deflate");
        }
        else if (encodings.Contains("gzip"))
        {
            context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
            context.Response.AppendHeader("Content-Encoding", "gzip");
            context.Response.AppendHeader("X-CompressResponseStream", "gzip");
        }
        else
        {
            context.Response.AppendHeader("X-CompressResponseStream", "no-known-accept");
        }
    }
}

[编辑] 为了回应评论:

只需在Web服务操作的任何位置调用它,因为它会在响应中设置属性:

[OperationContract]
public ReturnType GetInformation(...) {
    // do some stuff
    CompressResponseStream();
}

我放弃了那个项目,但那看起来非常不错。如果您能提供一个应该调用您的函数的示例,我将接受您的答案。 - rekire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接