我目前正在为我的自托管 WCF REST 应用程序编写 GZIP 压缩。我有一个 .NET 'MessageEncoder' 类的自定义实现和一个 'WebContentTypeMapper' 类的自定义实现。
如何在“ReadMessage”函数和“GetMessageFormatForContentType”函数中检索 http 标头?我想在解压缩输入之前检查“Content-Encoding”标头的传入请求。
谢谢你。
这是你可以做的
if (WebOperationContext.Current.IncomingRequest.Headers["Content-Encoding"] == WHAT YOU WANT)
{
// Do what you like to do here
}
希望这可以帮助。
谢谢。
我不相信您将能够直接从 CustomMessageEncoder 获取标题。您可以做的是利用更新的 .NET 4.5 WCF BinaryMessageEncoderBindingElement。现在,这允许您指定压缩类型(例如 Gzip)并在尝试解压缩之前自动检测消息正文是否已压缩。有关更多详细信息,请参阅Windows Communication Foundation 4.5 中的新增功能。
如果您想访问标题,您可以尝试的一种方法是在IDispatchMessageInspector的实现中利用HttpRequestMessageProperty。
简单的例子:
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);
您可以尝试使用 WebOperationContext.Current 或 OperationContext.Current(取决于您的绑定)。但不幸的是,我认为您不能在 MessageEncoder 实现本身中执行此操作,因为在此过程中为时已晚,因为当 MessageEncoder 被要求写入消息内容时,消息帧(在本例中为 HTTP 标头)已经被写入。因此,您还需要以 IOperationBehavior 的形式将其他行为应用于相应地设置标头的操作。在我的一个个人实现中,我通过在 OperationContext 中添加一个带有自定义消息检查器的 GzipExtension 解决了这个问题。正如 Alex 所说,IIS 已经有一个称为动态压缩的功能,可以压缩任何已配置的内容类型。