Add Http Headers For WCF/Rest Services

Requirement: There is a BizTalk service exposed as a Request and Response Rest service. I need to pass message to that Rest service with some http headers. BizTalk service has to receive those headers and pass it to back end service.

How to send headers to BizTalk Rest Service From third party tools like Postman.

httpheaders1.png

In BizTalk Orchestration message assignment shape, we need to assign incoming message context properties to another message which we are sending to request and response logical port.

Message2(*) = Message1(*) 

In order to populate http headers in the message which is sending to destination system, we need to assign some properties at behaviour section of sendport.

Please follow steps below.

  1. we need to create a class library with below code, build it and Gac it.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Xml;

using System.ServiceModel.Configuration;

using System.ServiceModel.Description;

using System.ServiceModel.Dispatcher;

using System.ServiceModel.Channels;

using System.ServiceModel;

using System.Configuration;

namespace AppName.CustomBehaviors

{

    public class AddHttpHeaderInspector : IDispatchMessageInspector, IClientMessageInspector

    {      

        private const string Source = “AddHttpHeaderContextInspector”;

        private const string contextHttpHeaderNS = @”http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties”;

        private const string contextHttpHeaderName = “HttpHeaders”;

        private const string httpResponseMessagePropertyName = “httpResponse”;

       private string headerFields;       

        public string HeaderFields    

    {

            get

            {

                return headerFields;

            }

            set

            {

                headerFields = value;

            }

        }

        public AddHttpHeaderInspector(string httpHeaders)

        {

            this.HeaderFields = httpHeaders;

        }

        public AddHttpHeaderInspector()

        {

        }

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)

        {

        }

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)

        {

            //Adds any headers in the WCF.HttpHeaders context property to the HTTP Headers

            //expects headers in the form “Header1: Value1, Header2: Value2”

            const string httpHeadersKey = “http://schemas.microsoft.com/BizTalk/2003/file-properties#ReceivedFileName”;

            if (request.Properties.ContainsKey(httpHeadersKey))

            {

                Dictionary<string, string> httpHeadersContext = GetHttpHeadersContext(Convert.ToString(request.Properties[httpHeadersKey]));

                HttpRequestMessageProperty httpRequestMessage;

                object httpRequestMessageObject;

                if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))

                {

                    httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;

                }

                else

                {

                    httpRequestMessage = new HttpRequestMessageProperty();

                    request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);

                }

                string[] hdrs = HeaderFields.Split(new char[] { ‘,’ }, StringSplitOptions.RemoveEmptyEntries);

                foreach (string hdr in hdrs)

                {

                    String[] fixedHdr = hdr.Split(new char[] { ‘:’ }, StringSplitOptions.RemoveEmptyEntries);

                    if (fixedHdr.Length > 1)

                    {

                        httpRequestMessage.Headers[fixedHdr[0]] = fixedHdr[1];

                    }

                    else

                    {

                        if (httpHeadersContext.ContainsKey(fixedHdr[0]))

                        {

                            httpRequestMessage.Headers[fixedHdr[0]] = httpHeadersContext[fixedHdr[0]];

                        }

                    }

                }

            }

            return null;

        }        

   

        public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)

        {

            return null;

        }

        public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)

        {

            try

            {

                object objContextHttpHeaders;

                object objHttpResponse;

                HttpResponseMessageProperty httpResponseMessage;

                if (reply.Properties.TryGetValue(string.Format(“{0}#{1}”, contextHttpHeaderNS, contextHttpHeaderName), out objContextHttpHeaders))

                {

                    Dictionary<string, string> httpHeadersContext = GetHttpHeadersContext(Convert.ToString(objContextHttpHeaders));

                      //Dictionary<string, string> subhttpHeadersContext = null;

                    if (reply.Properties.TryGetValue(httpResponseMessagePropertyName, out objHttpResponse))

                    {

                        if (objHttpResponse == null)

                        {

                            httpResponseMessage = new HttpResponseMessageProperty();

                            AddHttpHeaderContextToResponseHeaders(httpHeadersContext, httpResponseMessage);

                            reply.Properties.Add(httpResponseMessagePropertyName, httpResponseMessage);

                        }

                        else

                        {

                            httpResponseMessage = objHttpResponse as HttpResponseMessageProperty;

                            httpResponseMessage.Headers.Clear();

                            string[] hdrs = HeaderFields.Split(new char[] { ‘,’ }, StringSplitOptions.RemoveEmptyEntries);

                            foreach (string hdr in hdrs)

                            {

                                String[] fixedHdr = hdr.Split(new char[] { ‘:’ }, StringSplitOptions.RemoveEmptyEntries);

                                if (fixedHdr.Length > 1)

                                {

                                    httpResponseMessage.Headers[fixedHdr[0]] = fixedHdr[1];

                                }

                                else

                                {

                                    if (httpHeadersContext.ContainsKey(fixedHdr[0]))

                                    {

                                        httpResponseMessage.Headers[fixedHdr[0]] = httpHeadersContext[fixedHdr[0]];

                                    }

                                }

                            }

                        }

                    }

                }

            }

            catch (Exception ex)

            {

               throw;

            }

        }

        private Dictionary<string, string> GetHttpHeadersContext(string rawHttpHeaders)

        {

            Dictionary<string, string> headersDictionary = new Dictionary<string, string>();

            string[] headerlines = rawHttpHeaders.Split(new char[] {‘\n’, ‘\r’}, StringSplitOptions.RemoveEmptyEntries);

            foreach (string headerline in headerlines)

            {

                string[] headerfields = headerline.Split(new char[]{‘:’}, StringSplitOptions.RemoveEmptyEntries);

                if (headerfields.Length > 1)

                {

                    headersDictionary.Add(headerfields[0], headerfields[1]);

                }

            }

            return headersDictionary;

        }

        private void AddHttpHeaderContextToResponseHeaders(Dictionary<string, string> httpHeadersContext, HttpResponseMessageProperty httpResponseMessage)

        {

            foreach (string headerName in httpHeadersContext.Keys)

            {

                httpResponseMessage.Headers.Add(headerName, httpHeadersContext[headerName]);

            }

        }

    } 

    public class AddHttpHeaderBehavior : IEndpointBehavior

    {

        private string headerFields;       

        public string HeaderFields

        {

            get

            {

                return headerFields;

            }

            set

            {

                headerFields = value;

            }

        }

        public AddHttpHeaderBehavior(string httpHeaders)

        {

            this.HeaderFields = httpHeaders;

        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)

        {

            AddHttpHeaderInspector inspector = new AddHttpHeaderInspector(HeaderFields);

            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);

        }

        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)

        {

            return;

        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)

        {

            AddHttpHeaderInspector headerInspector = new AddHttpHeaderInspector(HeaderFields);

            clientRuntime.MessageInspectors.Add(headerInspector);

         }

       

        public void Validate(ServiceEndpoint endpoint)

        {

            return;

        }

    }

    public class AddHttpHeaderBehaviorExtensionElement : BehaviorExtensionElement

    {

        [ConfigurationProperty(“HeaderFields”, DefaultValue = “”, IsRequired = false)]

        public string HeaderFields

        {

            get { return (string)base[“HeaderFields”]; }

            set { base[“HeaderFields”] = value; }

        }

        protected override object CreateBehavior()

        {

            return new AddHttpHeaderBehavior(HeaderFields);

        }

        public override Type BehaviorType

        {

            get { return typeof(AddHttpHeaderBehavior); }

        }

    }

}

2) Mention fully qualified name of the above dll in the Machine.config like below.

We have to include below configuration entry in behaviorExtensions within machine.config file located in below mentioned folders.

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\

       <add name=”AddHttpHeader” type=”AppName.CustomBehaviors.AddHttpHeaderBehaviorExtensionElement, AppName.CustomBehaviors, Version=1.0.0.0, Culture=neutral, PublicKeyToken=XXXXXXX”/>

3) In send port, we need to apply EndpointBehaviors under Behavior tab and mention the header field names like below.

httpheaders2.png

Now you will be able to send the HttpHeaders along with outgoing message.

BizTalk Server Monitoring

One response to “Add Http Headers For WCF/Rest Services”

  1. […] Add Http Headers For BizTalk WCF/Rest Services by Vinay […]

    Like

Leave a comment