Я пытаюсь добавить сжатие сообщений в свой сервис WCF, но я застрял ...
Пока у меня есть:
Реализация MessageEncoder:
public class CompressionEncoder : MessageEncoder
{
public CompressionEncoderFactory _factory;
public const string GZipContentType = "application/x-gzip";
public override string ContentType
{
get
{
return GZipContentType;
}
}
public override string MediaType
{
get { return ContentType; }
}
public override MessageVersion MessageVersion
{
get { return _factory.MessageVersion; }
}
public CompressionEncoder(CompressionEncoderFactory factory)
{
_factory = factory;
}
public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)
{
var decompressedStream = new GZipStream(stream, System.IO.Compression.CompressionMode.Decompress, false);
XmlReader reader = XmlReader.Create(decompressedStream);
Message msg = Message.CreateMessage(reader, maxSizeOfHeaders, _factory.MessageVersion);
msg.Properties.Encoder = this;
return msg;
}
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{
MemoryStream stream = new MemoryStream(buffer.Array, buffer.Offset, buffer.Count);
GZipStream decompressedStream = new GZipStream(stream, System.IO.Compression.CompressionMode.Decompress);
return ReadMessage(decompressedStream, int.MaxValue);
}
public override void WriteMessage(Message message, Stream stream)
{
GZipStream compressedStream = new GZipStream(stream, System.IO.Compression.CompressionMode.Compress, true);
XmlWriter writer = XmlWriter.Create(compressedStream);
message.WriteMessage(writer);
}
public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
{
MemoryStream stream = new MemoryStream();
GZipStream compressedStream = new GZipStream(stream, System.IO.Compression.CompressionMode.Compress, true);
XmlWriter writer = XmlWriter.Create(compressedStream);
message.WriteMessage(writer);
writer.Close();
int messageLength = (int)compressedStream.Length;
byte[] messageBytes = new byte[messageLength];
compressedStream.Read(messageBytes, 0, messageLength);
int totalLength = messageLength + messageOffset;
byte[] totalBytes = bufferManager.TakeBuffer(totalLength);
Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);
ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);
return byteArray;
}
}
Реализация MessageEncoderFactory:
public class CompressionEncoderFactory : MessageEncoderFactory
{
CompressionMessageEncodingBindingElement _element;
public CompressionEncoderFactory(CompressionMessageEncodingBindingElement element)
{
_element = element;
}
public override MessageEncoder Encoder
{
get { return new CompressionEncoder(this); }
}
public override MessageVersion MessageVersion
{
get { return _element.MessageVersion; }
}
}
Реализация MessageEncodingBindingElement:
public sealed class CompressionMessageEncodingBindingElement : MessageEncodingBindingElement
{
MessageVersion _messageVersion = MessageVersion.None;
public override MessageEncoderFactory CreateMessageEncoderFactory()
{
return new CompressionEncoderFactory(this);
}
public override MessageVersion MessageVersion
{
get
{
return _messageVersion;
}
set
{
_messageVersion = value;
}
}
public override BindingElement Clone()
{
return new CompressionMessageEncodingBindingElement();
}
}
Реализация BindingElementExtensionElement:
public class CompressionBindingElementExtensionElement : BindingElementExtensionElement
{
public override Type BindingElementType
{
get { return typeof(CompressionMessageEncodingBindingElement); }
}
protected override System.ServiceModel.Channels.BindingElement CreateBindingElement()
{
return new CompressionMessageEncodingBindingElement();
}
}
В web.config я добавил это:
<service name="MyService">
<endpoint address="" binding="customBinding" bindingConfiguration="CompressionBinding" contract="IMyService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
...
<bindings>
<customBinding>
<binding name="CompressionBinding">
<messageCompression />
<httpTransport authenticationScheme="Anonymous"></httpTransport>
</binding>
</customBinding>
</bindings>
...
<extensions>
<bindingElementExtensions>
<add name="messageCompression" type="MyNamespace.CompressionBindingElementExtensionElement, MyNamespace" />
</bindingElementExtensions>
</extensions>
Но когда я запускаю клиент и вызываю какой-то сервисный код, я получаю следующую ошибку:
The message version of the outgoing message (EnvelopeNone (http://schemas.microsoft.com/ws/2005/05/envelope/none) AddressingNone (http://schemas.microsoft.com/ws/2005/05/addressing/none)) does not match that of the encoder (Soap12 (http://www.w3.org/2003/05/soap-envelope) Addressing10 (http://www.w3.org/2005/08/addressing)). Make sure the binding is configured with the same version as the message.
Что я делаю не так?