我已经构建了自己的WCF频道,其中包含所有必要的内容(如编码器,绑定等),以便与ServiceHost一起使用。
我只想构建“频道堆栈”,不在“服务模型”中进行任何规范。为了实现这一点,我的编码器返回完美的ServiceModel.Messages与XML信息集,就像其他频道一样。
让我们假设以下服务实现:
[ServiceContract(Namespace = "http://MyNS")]
public interface IService1
{
[OperationContract(IsOneWay = true)]
void dummy();
}
public class Service1 : IService1
{
public void dummy()
{
Console.WriteLine("In Service1:dummy()");
}
}
我通过其他绑定使用了此服务,并跟踪了以下ServiceModel.Message内容(SOAP格式):
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://MyNS/IService1/dummy</a:Action>
<a:To s:mustUnderstand="1">amqp://localhost</a:To>
</s:Header>
<s:Body>
<dummy xmlns="http://MyNS"></dummy>
</s:Body>
</s:Envelope>
然后(只是调试)我改变了我的编码器,总是返回此消息。当我使用我的自定义通道时,WCF的运行时重放带有故障消息告诉:
“由于EndpointDispatcher上的AddressFilter不匹配,无法在接收方处理带有To'的消息。检查发送方和接收方的EndpointAddresses是否一致。”
我读到默认的EndPointDispatcher.AddressFilter只是查看“TO”标题并将消息传递给相应的服务。其他绑定会发生这种情况,为什么自己的自定义频道也不会发生?
有什么方法可以检查一下默认的AddressFilter在做什么?
由于
答案 0 :(得分:2)
这个问题就是我创建消息的方式:
SimpleMessageBody body = new SimpleMessageBody("<dummy xmlns=\"http://MyNS\"></dummy>");
Message message = Message.CreateMessage(MessageVersion.Default, "http://MyNS/IService1/dummy", body);
MessageHeader toHeader = MessageHeader.CreateHeader("a:To", "", "amqp://localhost/", true); // DON'T DO THIS!!!
message.Headers.Add(toHeader);
“Action”和“To”是wcf存储在特定Message类字段中的特殊标头。必须像这样指定“To”标题:
message.Headers.To = new Uri("amqp://localhost/");
很难检测到错误,因为当我们查看message.ToString()时,我们会在正确的位置看到所有内容......