WCF Tutorial
www.Learn2Expert.net A new ASP.Net MVC 4, SSIS, Interview Q/A tutorial - Visit - www.Learn2Expert.net
Skip Navigation LinksHomeCustom Message Header No of Views: 103569

Custom message header

This article explains about customizing the wcf message flowing between service and client.

There are certain scenario in which you to pass some information from client to service, but not as parameter in operation contracts. Example, logging system at the service we need to log user or machine information, which made request to the service. In this kind of scenario we should not pass user or machine information as parameter in operation contract. Instead we can pass the information through message flowing between client and service vice versa. The information we need to send can be appended with message header and it can be received at the server side.

Let as create sample service and client application, in which client will send “User name” information through request message and service will respond with confirmation message.

I have created Math service with Add and Subtract functionality. Client consuming this service will send his user name information as string with requested message. Once request reached the service, it will read the information from the message header and display using console window. When service responding to the client, along with operation result, it will also send confirmation message to client through message header.

Step 1: Create IMathService interface decorated with Service and Operational contract attribute

IMathService.vb

<ServiceContract()> _
Public Interface IMathService
    <OperationContract()> _
    Function Add(ByVal a As Integer, ByVal b As Integer) As Integer
    <OperationContract()> _
    Function Subtract(ByVal a As Integer, ByVal b As Integer) As Integer
End Interface

Step 2:In this class, we have implemented Add and Subtract functionality.

PrintRequestedUserID() method will read the “UserID” message header from incoming message using OperationContext. This User information is displayed in console window.

SendResponseWithMessage() method will send a confirmation message to the client as Message header through Operation context.

MathService.vb

Public Class MathService
    Implements IMathService

    Public Function Add(ByVal a As Integer, ByVal b As Integer) As Integer 
    Implements IMathService.Add
        'This method call will retrive message send from client using MessageHeader
        PrintRequestedUserID()
        'This method call will send message to client using MessageHeader
        SendResponseWithMessage()
        Return a + b

    End Function

    Public Function Subtract(ByVal a As Integer, ByVal b As Integer) As Integer 
    Implements IMathService.Subtract
        'This method call will retrive message send from client using MessageHeader
        PrintRequestedUserID()
        'This method call will send message to client using MessageHeader
        SendResponseWithMessage()
        Return a - b
    End Function

    Private Sub PrintRequestedUserID()
        Dim userID As String = String.Empty
        'Read the message header using "Name" and "NameSpace"
        userID = OperationContext.Current.IncomingMessageHeaders
                                    .GetHeader(Of String)("UserID", "ns")
        Console.WriteLine("Requested user: " + userID)
    End Sub

    Private Sub SendResponseWithMessage()
        'Creating new message header with "Content" value assigned in constructor
        Dim mess As New MessageHeader(Of String)("This is sample message from service")
        'Assigning Name and NameSpace to the message header value at server side
        Dim header As System.ServiceModel.
                    Channels.MessageHeader = mess.GetUntypedHeader("ServiceMessage", "ns")
        'Adding message header with OperationContext 
        'which will be received at the client side
        OperationContext.Current.OutgoingMessageHeaders.Add(header)
    End Sub
End Class

Step 3: Hosting the MathService using console application

MyServiceHost.vb

       Module MyServiceHost

    Sub Main()
        'Hosting the Math service using console application
        Dim host As New ServiceHost(GetType(MyService.MathService))
        host.Open()
        Console.WriteLine("Service is running... Press  to exit.")
        Console.ReadLine()
    End Sub

End Module

Web.Config

      <system.serviceModel>
    <services><service name="MyService.MathService" 
    behaviorConfiguration="MyServiceBehavior">
        <endpoint address ="MathService" binding="basicHttpBinding" 
        contract="MyService.IMathService"/>
        <endpoint  address="mex" binding="mexHttpBinding" 
        contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8090/MyService"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors >
        <behavior name ="MyServiceBehavior">
          <serviceMetadata httpGetEnabled ="true"/>
            <serviceDebug includeExceptionDetailInFaults ="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Step 4: Created console client application which add “UserID” as message header to service using Operation context before calling Add() functionality. Once the response is received from the service, it is trying to read the confirmation message from service using Operation context.

Sub Main()
        'Creating proxy class for service
        Dim proxy As IMathService = Nothing
        proxy = ChannelFactory(Of IMathService).CreateChannel(New BasicHttpBinding(), 
                    New EndpointAddress("http://localhost:8090/MyService/MathService"))

        'Lifetime of OperationContextScope defines the scope for OperationContext.
        Dim scope As OperationContextScope = Nothing
        scope = New OperationContextScope(proxy)
       
        'Creating new message header with "Content" value assigned in constructor
        Dim mess As New MessageHeader(Of String)
                         (System.Security.Principal.WindowsIdentity.GetCurrent().Name)
        'Assigning Name and NameSpace to the message header value at client side
        Dim header As System.ServiceModel.Channels.MessageHeader 
                                    = mess.GetUntypedHeader("UserID", "ns")
        'Adding message header with OperationContext 
        'which will be received at the server side
        OperationContext.Current.OutgoingMessageHeaders.Add(header)

        'Making service call
        Console.WriteLine("Sum of {0},{1}={2}", 1, 2, proxy.Add(1, 2))
        'Displaying confrimation message from service
        Console.WriteLine("Response Message: " + OperationContext.Current.
                    IncomingMessageHeaders.GetHeader(Of String)("ServiceMessage", "ns"))
        Console.ReadLine()
    End Sub

End Module

<ServiceContract()> _
Public Interface IMathService
    Inherits IClientChannel

    <OperationContract()> _
    Function Add(ByVal a As Integer, ByVal b As Integer) As Integer
    <OperationContract()> _
    Function Subtract(ByVal a As Integer, ByVal b As Integer) As Integer
End Interface

Step 5: Run the MyServiceHost

Step 6: Run the MyClientApplication

Below figure shows the message flowing between service and client

Client application output

Console hosted service output screen

Conclusion:

This article explain about customizing the wcf message header

Tips!

  • Always create the service with Interface->Implementation format, mention the contract in Interface.
  • Define the service in Class library and refer the class library in Host project. Don’t use service class in host project.
  • Change the instance mode to per call as default.
  • Always catch exception using try/catch block and throw exception using FaultException < T >.
  • Logging and Include exception should be enable while compiling the project in debug mode. While in production deployment disable the logging and Include exception details.