给定一个 REST 服务 POST 调用:
[WebInvoke] // POST
string PostItem(PostItemContract contract);
在自定义绑定 (web.config) 中使用自定义 gzip 编码器:
<customBinding>
<binding name="customHttpGzipBindingConfig">
<!-- Normally would use binaryMessageEncoding, textMessageEncoding or webMessageEncoding here -->
<gzipMessageEncoding innerMessageEncoding="webMessageEncoding"/>
<httpTransport ...>
</binding>
</customBinding>
我收到一个错误:
InvalidOperationException:传入消息具有意外的消息格式“原始”。该操作的预期消息格式为“Xml”、“Json”。这可能是因为尚未在绑定上配置 WebContentTypeMapper。有关详细信息,请参阅 WebContentTypeMapper 的文档。
修改 web 配置以使用 webMessageEncoding 而不是 gzipMessageEncoding 可以清除错误。
所以我想我想让自定义 gzipMessageEncoding 表现得好像它是一个 webMessageEncoding:
我首先创建了 GzipWebContentTypeMapper 类:WebContentTypeMapper 其中 GetMessageFormatForContentType() 只返回 WebContentFormat.Xml;
然后对基于 MSDN 示例的编码器进行了一些修改:
class GZipMessageEncoder : MessageEncoder
{
public override bool IsContentTypeSupported(string contentType)
{
// A BP here says it is returning true, this is where the
// custom GetMessageFormatForContentType() is getting called.
return innerEncoder.IsContentTypeSupported(contentType);
}
// ...
}
public class GZipMessageEncodingElement : BindingElementExtensionElement
{
public override Type BindingElementType
{
get { return typeof(WebMessageEncodingBindingElement); } // just to see
}
public override void ApplyConfiguration(BindingElement bindingElement)
{
GZipMessageEncodingBindingElement binding = (GZipMessageEncodingBindingElement)bindingElement;
WebMessageEncodingBindingElement element = new WebMessageEncodingBindingElement();
// responsible for mapping from Content-Type to WCF xml/json/raw/default formats.
element.ContentTypeMapper = new GzipWebContentTypeMapper();
binding.InnerMessageEncodingBindingElement = element;
}
// ...
}
调试器显示:
GzipWebContentTypeMapper 确实被调用并返回 WebContentFormat.Xml;
GZipMessageEncoder.IsContentTypeSupported 返回 true。
显式设置格式也不起作用(?):
[WebInvoke(RequestFormat=WebMessageFormat.Xml)]
string PostItem(PostItemContract contract);
在 web.config 中,我尝试在自定义 gzip 编码器之前/之后添加 webMessageEncoding,但它没有帮助。
任何想法 GZipMessageEncoder.IsContentTypeSupported 返回 true 后会发生什么?
GzipWebContentTypeMapper(成功返回 WebContentFormat.Xml)的结果将存储在哪里,它怎么会被忽略?