WCF将自定义HTTP标头添加到请求中

时间:2012-09-30 11:54:39

标签: c# wcf soap

我在WCF服务上解析消息时遇到问题。 我运行了WCF应用程序的服务器端。另一家公司发给我这样的HTTP POST请求:

POST /telemetry/telemetryWebService HTTP/1.1
Host: 192.168.0.160:12123
Content-Length: 15870
Expect: 100-continue
Connection: Keep-Alive

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <wsse:Security> ... </wsse:Security>
  </soapenv:Header>
<soapenv:Body>
...
</soapenv:Body>
</soapenv:Envelope>

如何在此HTTP请求中看到此消息,缺少2个重要标题:肥皂操作内容类型。这就是我的服务无法正确处理此请求的原因。

我需要抓住请求,直到它开始处理并手动添加这些标题。

我已经尝试了 IDispatchMessageInspector ,但没有任何结果。

2 个答案:

答案 0 :(得分:2)

使用SOAP消息时,服务器端的调度是根据soap操作头完成的,该操作头指示调度程序应该处理消息的相应方法是什么。

有时soap操作为空或无效(java interop)。

我认为您最好的选择是实现IDispatchOperationSelector。这样,您可以覆盖服务器将传入消息分配给操作的默认方式。

在下一个示例中,调度程序将SOAP主体内第一个元素的名称映射到消息将转发到的操作名称。

 public class DispatchByBodyElementOperationSelector : IDispatchOperationSelector
    {
        #region fields

        private const string c_default = "default";
        readonly Dictionary<string, string> m_dispatchDictionary;

        #endregion

        #region constructor

        public DispatchByBodyElementOperationSelector(Dictionary<string, string> dispatchDictionary)
        {
            m_dispatchDictionary = dispatchDictionary;
            Debug.Assert(dispatchDictionary.ContainsKey(c_default), "dispatcher dictionary must contain a default value");
        }

        #endregion

        public string SelectOperation(ref Message message)
        {
            string operationName = null;
            var bodyReader = message.GetReaderAtBodyContents();
            var lookupQName = new
               XmlQualifiedName(bodyReader.LocalName, bodyReader.NamespaceURI);

            // Since when accessing the message body the messageis marked as "read"
            // the operation selector creates a copy of the incoming message 
            message = CommunicationUtilities.CreateMessageCopy(message, bodyReader);

            if (m_dispatchDictionary.TryGetValue(lookupQName.Name, out operationName))
            {
                return operationName;
            }
            return m_dispatchDictionary[c_default];
        }
    }

答案 1 :(得分:0)

谢谢大家。

1)您需要创建自己的自定义邮件编码器,默认情况下您可以在其中创建内容类型。 Yщu可以通过示例阅读here

2)您需要创建自定义邮件过滤器,因为您需要在没有 SoapAction

的情况下跳过邮件
public class CustomFilter : MessageFilter
{
    private int minSize;
    private int maxSize;
    public CustomFilter()
        : base()
    {

    }
    public CustomFilter(string paramlist)
        : base()
    {
        string[] sizes = paramlist.Split(new char[1] { ',' });
        minSize = Convert.ToInt32(sizes[0]);
        maxSize = Convert.ToInt32(sizes[1]);
    }
    public override bool Match(System.ServiceModel.Channels.Message message)
    {
        return true;
    }
    public override bool Match(MessageBuffer buffer)
    {
        return true;
    }
}

3)您需要创建自定义消息选择器,以便将传入消息分配给操作。 Cyber​​maxs 的例子非常好。