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: 受信メッセージに予期しないメッセージ形式 'Raw' があります。この操作で想定されるメッセージ形式は、'Xml'、'Json' です。これは、バインディングで WebContentTypeMapper が構成されていないことが原因である可能性があります。詳細については、WebContentTypeMapper のドキュメントを参照してください。
gzipMessageEncoding の代わりに webMessageEncoding を使用するように Web 構成を変更すると、エラーがクリアされます。
したがって、カスタム 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 を正常に返す) の結果はどこに保存され、どのように無視されるのでしょうか?