WCF add custom HTTP header to request

I have a problem processing messages in the WCF service. I ran the server side for the WCF application. Another company sends me this HTTP POST request:

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> 

As you can see, there are two important headers in this HTTP request: Action Soap and Content-type . Therefore, my service cannot process this request correctly.

I need to catch the request until it starts to process, and manually add these headers.

I already tried IDispatchMessageInspector , but without any results.

+4
source share
2 answers

Thanks to everyone.

1) You need to create your own special message encoder , where you can create a default Content-type. You can read here with examples.

2) You need to create a custom message filter , because you need to skip messages without 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) To assign incoming messages to operations, you need to create a custom message selector . Cybermaxs example is very good.

0
source

When working with SOAP messages, server-side scheduling is performed in accordance with the soap action header, which instructs the dispatcher, which is the appropriate method that should process the message.

Sometimes the action of the soap is empty or invalid (java interop).

I think that you are best off implementing IDispatchOperationSelector. In doing so, you can override the default method that the server assigns to incoming messages for operations.

In the following example, the dispatcher will map the name of the first element inside the SOAP body to the name of the operation to which the message will be sent for processing.

  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]; } } 
+2
source

Source: https://habr.com/ru/post/1437030/


All Articles