I am writing a custom WCF Message Encoder and when a request message gets into this encoder, I need to get access to the WCF Message Properties (or Headers for that matter).
The problem is that the OperationContext.Current is null and I don't have access to the actual WCF Message in my Encoder class.
Is there a way to get this right? (knowing that I don't have full control over the client).
Best regards
Here is a demo for custom MessageEncoder.
the purpose of this demo: client will save a string property into message and server program will print out this string when receiving a message.
Common part:
public class MyMessageEncoder : MessageEncoder {
public MessageEncoder InnerMessageEncoder { get; set; }
public String Greeting { get; private set; }
public MyMessageEncoder(MessageEncoder innerMessageEncoder, String greeting) {
this.InnerMessageEncoder = innerMessageEncoder;
this.Greeting = greeting;
}
public override string ContentType {
get { return this.InnerMessageEncoder.ContentType; }
}
public override string MediaType {
get { return this.InnerMessageEncoder.MediaType; }
}
public override MessageVersion MessageVersion {
get { return this.InnerMessageEncoder.MessageVersion; }
}
public override T GetProperty<T>() {
return this.InnerMessageEncoder.GetProperty<T>();
}
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType) {
Message message = this.InnerMessageEncoder.ReadMessage(buffer, bufferManager, contentType);
Console.WriteLine("greeting = " + message.Properties["greeting"].ToString());
return message;
}
public override Message ReadMessage(System.IO.Stream stream, int maxSizeOfHeaders, string contentType) {
Message message = this.InnerMessageEncoder.ReadMessage(stream, maxSizeOfHeaders, contentType);
Console.WriteLine("greeting = " + message.Properties["greeting"].ToString());
return message;
}
public override ArraySegment<byte> WriteMessage(
Message message, int maxMessageSize,
BufferManager bufferManager, int messageOffset) {
message.Properties["greeting"] = this.Greeting;
return this.InnerMessageEncoder.WriteMessage(
message, maxMessageSize, bufferManager, messageOffset);
}
public override void WriteMessage(Message message, System.IO.Stream stream) {
message.Properties["greeting"] = this.Greeting;
this.InnerMessageEncoder.WriteMessage(message, stream);
}
}
public class MyMessageEncoderFactory : MessageEncoderFactory {
public MessageEncoderFactory InnerMessageEncoderFactory { get; private set; }
public String Greeting { get; private set; }
public MyMessageEncoderFactory(MessageEncoderFactory innerMessageEncoderFactory, String greeting) {
this.InnerMessageEncoderFactory = innerMessageEncoderFactory;
this.Greeting = greeting;
}
public override MessageEncoder Encoder {
get {
return new MyMessageEncoder(
this.InnerMessageEncoderFactory.Encoder, this.Greeting);
}
}
public override MessageVersion MessageVersion {
get { return this.InnerMessageEncoderFactory.MessageVersion; }
}
}
public class MyTextEncodingElement: BindingElementExtensionElement {
[ConfigurationProperty("greeting")]
public String Greeting {
get { return (String)this["greeting"]; }
set { this["greeting"] = value; }
}
[ConfigurationProperty("textEncoding")]
public TextMessageEncodingElement TextEncoding {
get { return (TextMessageEncodingElement)this["textEncoding"]; }
set { this["textEncoding"] = value; }
}
public override Type BindingElementType {
get { return typeof(MyTextMessageEncodingBindingElement); }
}
protected override BindingElement CreateBindingElement() {
var textBindingElement = new TextMessageEncodingBindingElement();
if (this.TextEncoding != null) {
this.TextEncoding.ApplyConfiguration(textBindingElement);
}
return new MyTextMessageEncodingBindingElement(textBindingElement, this.Greeting);
}
}
public class MyTextMessageEncodingBindingElement : MessageEncodingBindingElement {
public TextMessageEncodingBindingElement TextEncodingElement { get; private set; }
public String Greeting { get; private set; }
private MyTextMessageEncodingBindingElement() {
}
public MyTextMessageEncodingBindingElement(
TextMessageEncodingBindingElement textEncodingElement, String greeting) {
this.TextEncodingElement = textEncodingElement;
this.Greeting = greeting;
}
public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context) {
context.BindingParameters.Add(this);
return base.BuildChannelFactory<TChannel>(context);
}
public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context) {
context.BindingParameters.Add(this);
return base.BuildChannelListener<TChannel>(context);
}
public override MessageEncoderFactory CreateMessageEncoderFactory() {
return new MyMessageEncoderFactory(
this.TextEncodingElement.CreateMessageEncoderFactory(),
this.Greeting);
}
public override MessageVersion MessageVersion {
get {
return this.TextEncodingElement.MessageVersion;
}
set {
this.TextEncodingElement.MessageVersion = value;
}
}
public override BindingElement Clone() {
var textEncodingElement = new TextMessageEncodingBindingElement() {
MaxReadPoolSize = this.TextEncodingElement.MaxReadPoolSize,
MaxWritePoolSize = this.TextEncodingElement.MaxWritePoolSize,
MessageVersion = this.TextEncodingElement.MessageVersion,
WriteEncoding = this.TextEncodingElement.WriteEncoding
};
return new MyTextMessageEncodingBindingElement(
textEncodingElement, this.Greeting);
}
}
server program:
[ServiceContract(Name="CalculatorService", Namespace="http://www.artech.com")]
public interface ICalculatorService {
[OperationContract]
int Add(int x, int y);
}
public class CalculatorService : ICalculatorService {
public Int32 Add(Int32 x, Int32 y) {
Console.WriteLine("{0}: service method called (x = {1}, y = {2})",
Thread.CurrentThread.ManagedThreadId, x, y);
return x + y;
}
}
class Program {
static void Main(string[] args) {
using (var serviceHost = new ServiceHost(typeof(CalculatorService))) {
serviceHost.Opened += delegate {
Console.WriteLine("{0}: service started",
Thread.CurrentThread.ManagedThreadId);
};
serviceHost.Open();
Console.Read();
}
}
}
server configruation:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="myTextEncoding"
type="Common.MyTextEncodingElement, Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</bindingElementExtensions>
</extensions>
<bindings>
<customBinding>
<binding name="myTextEncoding">
<myTextEncoding greeting="we dont use this">
<textEncoding maxReadPoolSize="64"
maxWritePoolSize="16"
messageVersion="Soap11"
writeEncoding="utf-8">
<readerQuotas maxArrayLength="16384"
maxBytesPerRead="4096"
maxDepth="32"
maxStringContentLength="8192"
maxNameTableCharCount="16384" />
</textEncoding>
</myTextEncoding>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<services>
<service name="WcfService.CalculatorService">
<endpoint address="http://127.0.0.1:3722/calculatorservice"
binding="customBinding"
bindingConfiguration="myTextEncoding"
contract="Contract.ICalculatorService" />
</service>
</services>
</system.serviceModel>
</configuration>
client side:
class Program {
static void Main(string[] args) {
using (var channelFactory =
new ChannelFactory<ICalculatorService>("calculatorservice")) {
ICalculatorService proxy = channelFactory.CreateChannel();
Console.WriteLine(proxy.Add(1, 2));
Console.Read();
}
Console.Read();
}
}
client configuration:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="myTextEncoding"
type="Common.MyTextEncodingElement, Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</bindingElementExtensions>
</extensions>
<bindings>
<customBinding>
<binding name="myTextEncoding">
<myTextEncoding greeting="hello client">
<textEncoding maxReadPoolSize="64"
maxWritePoolSize="16"
messageVersion="Soap11"
writeEncoding="utf-8">
<readerQuotas maxArrayLength="16384"
maxBytesPerRead="4096"
maxDepth="32"
maxStringContentLength="8192"
maxNameTableCharCount="16384" />
</textEncoding>
</myTextEncoding>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint name="calculatorservice"
address="http://127.0.0.1:3722/calculatorservice"
binding="customBinding"
bindingConfiguration="myTextEncoding"
contract="Contract.ICalculatorService"/>
</client>
</system.serviceModel>
</configuration>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.