Attachment:
CustomMessageHeader.zipThis 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.vbThere 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
<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
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
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
<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>
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 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
No comments:
Post a Comment