C# 获取对WCF编码器中传入消息属性的访问权限(OperationContext.Current为null)
我正在编写一个自定义WCF消息编码器,当请求消息进入该编码器时,我需要访问WCF消息属性(或相应的标题)。C# 获取对WCF编码器中传入消息属性的访问权限(OperationContext.Current为null),c#,wcf,C#,Wcf,我正在编写一个自定义WCF消息编码器,当请求消息进入该编码器时,我需要访问WCF消息属性(或相应的标题)。 问题是OperationContext.Current为null,并且我无法访问编码器类中的实际WCF消息 有没有办法把这件事做好?(知道我不能完全控制客户) 致以最诚挚的问候这里是定制MessageEncoder的演示 这个演示的目的是:客户端将把字符串属性保存到消息中,服务器程序在收到消息时将打印出这个字符串 公共部分: public class MyMessageEncoder :
问题是OperationContext.Current为null,并且我无法访问编码器类中的实际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);
}
}
服务器配置:
<?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();
}
}
类程序{
静态void Main(字符串[]参数){
使用(var)通道工厂=
新通道工厂(“计算器服务”)){
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>
谢谢,尚未在innermessage上找到ReadMessage!我将进一步研究,但这似乎是正确的方法!属性“InnerMessageEncoder”实际上是在类“MyMessageEncoder”中定义的。将修改此答案,并在今天晚些时候提供完整的演示:)
<?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>