获取对WCF编码器中传入消息属性的访问权限(OperationContext.Current为null)
本文关键字:权限 访问权 OperationContext Current null 访问 编码器 WCF 属性 消息 获取 | 更新日期: 2023-09-27 17:59:30
我正在编写一个自定义WCF消息编码器,当请求消息进入该编码器时,我需要访问WCF消息属性(或标头)
问题是OperationContext。Current为null,我无法访问Encoder类中的实际WCF消息。
有没有办法做到这一点?(知道我不能完全控制客户)。
向致以最良好的问候
下面是自定义MessageEncoder的演示。
这个演示的目的是:客户端将把一个字符串属性保存到消息中,服务器程序将在收到消息时打印出这个字符串。
通用部分:
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);
}
}
服务器程序:
[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();
}
}
}
服务器配置:
<?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>
客户端:
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();
}
}
客户端配置:
<?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>