在WCF MessageEncoder中获取HTTP标头

时间:2012-08-20 13:50:51

标签: c# .net wcf http rest

我正在为我的自主WCF REST应用程序编写GZIP压缩。我有一个.NET'MessageEncoder'类的自定义实现和'WebContentTypeMapper'类的自定义实现。

如何在“ReadMessage”函数和“GetMessageFormatForContentType”函数中检索http标头?在解压缩输入之前,我想检查传入的'Content-Encoding'标头请求。

谢谢。

3 个答案:

答案 0 :(得分:3)

这是你可以做的

if (WebOperationContext.Current.IncomingRequest.Headers["Content-Encoding"] == WHAT YOU WANT)
{
            // Do what you like to do here
}

希望这有帮助。

感谢。

答案 1 :(得分:1)

您可以尝试使用WebOperationContext.Current或OperationContext.Current(取决于您的绑定)。 但不幸的是,我认为你不能在MessageEncoder实现中做到这一点,因为它在这个过程中为时已晚,因为当MessageEncoder被要求写入消息内容时,消息帧(在这种情况下是HTTP头)已经被写入了。因此,您还需要以IOperationBehavior的形式应用于相应设置标头的操作的其他行为。 在我的一个人工实现中,我通过在OperationContext中添加一个带有自定义消息检查器的GzipExtension来解决这个问题。 正如Alex所说,IIS已经有一个称为动态压缩的功能,可以压缩任何已配置的内容类型。

答案 2 :(得分:1)

我不相信您可以直接从CustomMessageEncoder获取标头。您可以做的是利用更新的.NET 4.5 WCF BinaryMessageEncoderBindingElement。现在,您可以指定压缩类型(例如Gzip),并在尝试解压缩之前自动检测邮件正文是否已压缩。有关详细信息,请参阅Whats's New in Windows Communication Foundation 4.5

如果您想要获得标题,可以尝试的一种方法是在HttpRequestMessageProperty的实现中使用IDispatchMessageInspector

简单示例:

    public class MyDispatchMessageInspector : IDispatchMessageInspector
    {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            object obj;
            if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out obj))
            {
                 var httpRequestMessageProperty = obj as HttpRequestMessageProperty;

                 if (httpRequestMessageProperty != null 
                         && !string.IsNullOrEmpty(httpRequestMessageProperty.Headers["content-encoding"]))
                 {
                    ...
                 }
            }
            return null;
     }
     ...
}

另一种选择是使用以下内容访问OperationContext

int index = System.ServiceModel.OperationContext.Current.IncomingMessageHeaders.FindHeader("content-encoding", "");
string contentEncodeHeaderValue = System.ServiceModel.OperationContext.Current.IncomingMessageHeaders.GetHeader<string>(index);