Saturday, October 6, 2012

How to read incoming and outgoing message in wcf

 

In this post,I will show you how to read outgoing and incoming message in wcf.

Create a new console application and add following assembly reference in the project

using System.ServiceModel;
using System.ServiceModel.Description;

and paste following code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace WCF_MessageInspector
{
    [ServiceContract]
    public interface IHelloService
    {
        [OperationContract]
        string Greet(string name);
    }
    [ConsoleServiceBehavior]
    [ServiceBehavior]
    public class HelloService : IHelloService
    {
        public string Greet(string name)
        {
            return "Hello ," + name;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string baseUrl = "http://localhost:12345";
            ServiceHost host = new ServiceHost(typeof(HelloService), new Uri(baseUrl));
            host.AddServiceEndpoint(typeof(IHelloService), new BasicHttpBinding(), "basic");
            // Check to see if the service host already has a ServiceMetadataBehavior
            ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
            // If not, add one
            if (smb == null)
                smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(smb);

            host.Open();
            Console.WriteLine("Service is ready");
            Console.Read();
        }
    }
}
Create a new class named  ConsoleMessageInspector and inherit it from following interfaces
IClientMessageInspector
IDispatchMessageInspector
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;

namespace WCF_MessageInspector
{
    public class ConsoleMessageInspector : IClientMessageInspector, IDispatchMessageInspector
    {
        public Message CreateMessage(Message message)
        {
            MessageBuffer buffer = message.CreateBufferedCopy(Int32.MaxValue);
            var messageCopy = buffer.CreateMessage();
            Console.WriteLine(messageCopy.ToString());
            return buffer.CreateMessage();

        }
        public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
        {
            request = CreateMessage(request);
            return null;
        }

        public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
            reply = CreateMessage(reply);
        }

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
            reply = CreateMessage(reply);
        }

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
        {
            request = CreateMessage(request);
            return null;
        }
    }
}
Create a new class named ConsoleEndpointBehavior and inherit it from following iterface
IEndpointBehavior
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Description;

namespace WCF_MessageInspector
{
   public class ConsoleEndpointBehavior:IEndpointBehavior
    {

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

        public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(new ConsoleMessageInspector());
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new ConsoleMessageInspector());
        }

        public void Validate(ServiceEndpoint endpoint)
        {
            
        }
    }
}
Now it’s time to apply custom inspector to the service.For this create a new class named  ConsoleServiceBehavior and inherit it from Attribute and IServiceBehavior
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Description;

namespace WCF_MessageInspector
{
   public class ConsoleServiceBehavior:Attribute,IServiceBehavior
    {
        public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {
            foreach (var item in serviceHostBase.Description.Endpoints)
            {
                item.Behaviors.Add(new ConsoleEndpointBehavior());
            }
        }

        public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {
            
        }
    }
}

Create a new Project named client and add service reference

Untitled

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            Proxy.HelloServiceClient client = new Proxy.HelloServiceClient();
            Console.WriteLine(client.Greet("Bill"));
        }
    }
}

 

Run both the application,and you will show that incoming and outgoing messages are captured

 

output

Complete code

Friday, October 5, 2012

How to read namespace based xml using Linq

In this post,I will show you how to read xml with namespace.For this demo,I will use following xml

structure

<?xml version="1.0" encoding="utf-8" ?>
<accounts xmlns="urn:account">
  <account>1001</account>
  <account>1002</account>
</accounts>

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace XLinq
{
    class Program
    {
        static void Main(string[] args)
        {
            var doc = XDocument.Load("accounts.xml");
            var query = from x in doc.Descendants("{urn:account}account")
                        select x;
            foreach (var item in query)
            {
                Console.WriteLine(item);
            }
        }
    }
}