Service Reference, MTOM and add custom values to HTTP Header Content-Type

455 Views Asked by At

I'm using a Windows Service with Net 4.6 and I've create a Service Reference in VS 2022 of a WSDL service and all works fine but now I've to add a param in HTTP Header Content-Type. The problem is that I'm using a MTOM Transport and seems I cant attach nothing to Content-Type Header. I'd tryed to implements a CustomBehaviour inherits IEndpointBehavior and relative CustomInspector of IClientMessageInspector in method BeforeSendRequest but seems that I cant read the header inside these because MTOM message create boundary elements AFTER this call.

In short, I've this HTTP header Content-Type

multipart/related;type="application/xop+xml";charset=UTF-8;start-info="application/soap+xml";boundary="uuid:00361b85-692d-43a1-9f17-57d70bbe26df+id=1"

And I've to "attach" some like this

action="{action}";

Is it possible?

This is my sample code

            WSHttpBinding wsHttpBinding = new WSHttpBinding();
            wsHttpBinding.Security.Mode = SecurityMode.Transport;
            wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
            wsHttpBinding.MessageEncoding = WSMessageEncoding.Mtom;
            
            Client = new ServiceClient(wsHttpBinding, new EndpointAddress(EndPoint));

Here I call my custom behaviour

Client.Endpoint.Behaviors.Add(new CustomBehavior(action));

then I implements the Behaviour

public class CustomBehavior : IEndpointBehavior
        {
            private string action = null;
            
            public CustomBehavior(string action, byte[] file)
            {
                this.action = action;
                
            }

            public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }

            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }

            public void Validate(ServiceEndpoint endpoint) { }

            public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            {
                clientRuntime.MessageInspectors.Add(new CustomInspector(this.action));
            }
        }
        private class CustomInspector : IClientMessageInspector
        {
            private string action;

            public CustomInspector(string action)
            {
                this.action = action;
            }

            public void AfterReceiveReply(ref Message reply, object correlationState)
            {

            }

            public object BeforeSendRequest(ref Message request, IClientChannel channel)
            {
               HttpRequestMessageProperty reqProps = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;

                if (reqProps != null)
                {
                    reqProps = new HttpRequestMessageProperty();
                }




                reqProps.Headers.Add("Content-Type", $"multipart/related;type=\"application/xop+xml\";charset=UTF-8;start-info=\"application/soap+xml\";action=\"{action}\";boundary=\"uuid:00361b85-692d-43a1-9f17-57d70bbe26df+id=1\";");
                request.Properties[HttpRequestMessageProperty.Name] = reqProps;


                return null;
            }
        }

then I use it

 using (OperationContextScope scope = new OperationContextScope((Client as DocumentRepository_PortTypeClient).InnerChannel))
            {

//I try to read header here but they are empty
var obj = OperationContext.Current.OutgoingMessageProperties;

response = Client.call(request);
}
1

There are 1 best solutions below

1
Jiayao On

wcf has some formatting requirements for http content-type headers such as this :

Content-Type: Multipart/Related; type="application/xop+xml";start-info="text/xml";boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1"

The format of the header output you added might be a little different from this. You can take a look at this document for more information.