MessageInspector – WCF
December 15, 2009 1 Comment
Actually I got one assignment from current job that when client call the service, I want to add some object that I can use at service side.
So basically, I want to try to display the SOAP message sent to the service host. In order to do this, you might want to pay attention to 3 things:
· System.ServiceModel.Configuration.BehaviorExtensionElement
· System.ServiceModel.Description.IEndpointBehavior
· System.ServiceModel.Dispatcher.IClientMessageInspector
You can fine code here : http://cid-39f476822b8257be.skydrive.live.com/self.aspx/.Public/WCF^_Demo/MitWCFDay1.zip
Here is the service…
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ServiceModel;
- using MitWCFDay2;
- namespace MitWCFDay1
- {
- [ServiceContract]
- [MyMessageInspector]
- public interface ICalcMath
- {
- [OperationContract]
- int AddNumber(int i, int j);
- }
- public class CalcMath : ICalcMath
- {
- #region ICalcMath Members
- public int AddNumber(int i, int j)
- {
- return i + j;
- }
- #endregion
- }
- }
If you observe carefully then one MyMessageInspector attribute is define to service. I’ll explain that later.
Now We have to create MyMessageInspector class and code is following…
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.ServiceModel.Channels;
- using System.ServiceModel;
- using System.ServiceModel.Description;
- using System.ServiceModel.Dispatcher;
- using System.ServiceModel.Configuration;
- namespace MitWCFDay1
- {
- class MyMessageInspector : Attribute, IClientMessageInspector, System.ServiceModel.Description.IEndpointBehavior
- {
- #region IClientMessageInspector Members
- public void AfterReceiveReply(ref Message reply, object correlationState)
- { // Ignore
- }
- public object BeforeSendRequest(ref Message request, IClientChannel channel)
- {
- Console.WriteLine(request.ToString());
- return null;
- }
- #endregion
- #region IEndpointBehavior Members
- public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
- { // Ignore
- }
- public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
- {
- clientRuntime.MessageInspectors.Add(new MyMessageInspector());
- }
- public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
- { // Ignore
- }
- public void Validate(ServiceEndpoint endpoint)
- { // Ignore
- }
- #endregion
- }
- public class CustomBehaviorSection : BehaviorExtensionElement
- {
- public override Type BehaviorType
- {
- get { return typeof(MyMessageInspector); }
- }
- protected override object CreateBehavior()
- {
- return new MyMessageInspector();
- }
- }
- public class Information
- {
- public static Information CurrentInformation { get; set; }
- public string ComputerName { get; set; }
- public string UserName { get; set; }
- public Information(string computerName,string userName)
- {
- if (CurrentInformation == null)
- {
- this.ComputerName = computerName;
- this.UserName = userName;
- CurrentInformation = this;
- }
- else
- CurrentInformation = this;
- }
- }
- }
Here MessageInspector class is responsible to set whatever client want to set. There is other class call CustomBehaviorSection and it is derived from BehaviorExtensionElement. We have to give this BehaviorExtensionElement into app.config file.
- <?xml version=“1.0“ encoding=“utf-8“ ?>
- <configuration>
- <system.serviceModel>
- <services>
- <service name=“MitWCFDay1.CalcMath“ behaviorConfiguration=“ForAuthorazation“>
- <endpoint address=“net.tcp://localhost:56/MyMathService“ binding=“netTcpBinding“ contract=“MitWCFDay1.ICalcMath“ bindingConfiguration=“ForSecurity“ name=“Binding1“ />
- <endpoint address=“http://localhost:560/MyMathService“ binding=“basicHttpBinding“ contract=“MitWCFDay1.ICalcMath“ name=“Binding2“ />
- <host>
- <baseAddresses>
- <add baseAddress=“net.tcp://localhost:56/MyMathService“/>
- </baseAddresses>
- </host>
- </service>
- </services>
- <client>
- <endpoint address=“net.tcp://localhost:56/MyMathService“ binding=“netTcpBinding“ contract=“MitWCFDay1.ICalcMath“ name=“Binding1“ behaviorConfiguration =“aa“ />
- <endpoint address=“http://localhost:560/MyMathService“ binding=“basicHttpBinding“ contract=“MitWCFDay1.ICalcMath“ name=“Binding2“ behaviorConfiguration=“aa“ />
- </client>
- <behaviors>
- <serviceBehaviors>
- <behavior name=“ForAuthorazation“>
- <serviceAuthorization serviceAuthorizationManagerType=“MitWCFDay1.CalcAutoMng,MitWCFDay1“ />
- </behavior>
- </serviceBehaviors>
- <endpointBehaviors >
- <behavior name=“aa“>
- <CustomBehaviorSection />
- </behavior>
- </endpointBehaviors>
- </behaviors>
- <extensions>
- <behaviorExtensions>
- <add name=“CustomBehaviorSection“ type=“MitWCFDay1.CustomBehaviorSection, MitWCFDay1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null“ />
- </behaviorExtensions>
- </extensions>
- <bindings>
- <netTcpBinding>
- <binding name=“ForSecurity“>
- <security mode=“Transport“>
- <transport clientCredentialType=“Windows“/>
- </security>
- </binding>
- </netTcpBinding>
- </bindings>
- </system.serviceModel>
- </configuration>
First we have created behaviorExtensions and after we have define that into endpointBehaviors.
now if you put break point on MessageInspector , before calling the service it will call the methods of MessageInspector class.
Don’t forget to add the attribute on service.. other wise throw the error…



Really good one. Can u please give the situation where we should used MessageInspector except security scenario.