WCF Custom Header with Silverlight

In my previous post “Client Additional Parameters using Custom Headers in WCF“, I discussed about passing additional parameters from client in SOAP header with WCF service by implementing IClientMessageInspector, IEndPointBehavior and BehaviorExtensionElement.

I am really glad to know that it help some of you. However, I have received some queries from readers for implementing custom headers with Silverlight client which I am going to discuss in this post.

While working on Silverlight client, we have limited framework available and to implement custom headers there are some slight changes:

  1. Instead of App.config or Web.config, you have ServiceReference.ClientConfig
  2. MessageHeader (Generic) class is not available instead you can use MessageHeader class
  3. There is no BehaviorExtensionElement class available in Silverlight 4 Runtime
  4. Since there is no BehaviorExtensionElement class, therefore you cannot define extension in .config file
  5. You need to programmatically bind/add custom endpoint behavior

I have pasted the code snippet below, that would work fine with Silverlight 4 client to pass custom header to WCF service.

IClientMessageInspector

   1:  public class MyMessageInspector : IClientMessageInspector
   2:  {
   3:      #region IClientMessageInspector Members
   4:   
   5:      public void AfterReceiveReply(ref Message reply,
   6:                                      object correlationState)
   7:      {
   8:          Debug.WriteLine("SOAP Response: {0}", reply.ToString());
   9:      }
  10:   
  11:      public object BeforeSendRequest(ref Message request,
  12:                                      IClientChannel channel)
  13:      {
  14:          const string STR_Customer_Unique_Id = "Customer Unique Id: 12345";
  15:          var header = MessageHeader.CreateHeader("Identity", 
  16:                                                  "http://www.adilmughal.com", 
  17:                                                  STR_Customer_Unique_Id);
  18:          request.Headers.Add(header);
  19:          Debug.WriteLine("SOAP Request: {0}", request.ToString());
  20:          return null;
  21:      }
  22:      #endregion
  23:  }

Note that the header is now created (see line 15) using simple MessageHeader class.

IEndPointBehavior

   1:  public class CustomBehavior : IEndpointBehavior
   2:  {
   3:      #region IEndpointBehavior Members
   4:   
   5:      public void AddBindingParameters(ServiceEndpoint endpoint,
   6:                                          BindingParameterCollection bindingParameters)
   7:      {
   8:      }
   9:   
  10:      public void ApplyClientBehavior(ServiceEndpoint endpoint,
  11:                                      ClientRuntime clientRuntime)
  12:      {
  13:          clientRuntime.MessageInspectors.Add(new MyMessageInspector());
  14:      }
  15:   
  16:      public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
  17:                                          EndpointDispatcher endpointDispatcher)
  18:      {
  19:      }
  20:   
  21:      public void Validate(
  22:          ServiceEndpoint endpoint)
  23:      {
  24:      }
  25:      #endregion
  26:  }

You may have observed that in contrast to previously discussed solution in last post, we are not implementing BehaviorExtensionElement any more.

Adding Behavior to Proxy

ServiceProxy.TestServiceClient proxy = new ServiceProxy.TestServiceClient();
proxy.Endpoint.Behaviors.Add(new CustomBehavior());

Without BehaviorExtensionElement, we cannot define custom endpoint behavior in .config file so need to plug it programmatically.

That is all. You may download code sample-LINK TO CODE. Hope this helps. If you have somewhat different solution, please do share.

Client Additional Parameters using Custom Headers in WCF

When building Service communication applications using Windows Communication Foundation, we often come to a situation where we have multiple clients communicating with WCF Service and we need to pass additional parameters from client to service. This may be due to number of reasons such as sharing a unique customer ID to identify certain elements for that particular client. In such scenarios, for every communication between client and server, you need this unique ID to treat each client accordingly.

Client-Server-Customer-Id-Parameter-WCF

In a typical disconnected environment over the internet you need to pass such data on each call to service and of course passing in each Service Method or Operation Call is confusing and not appropriate.

A good Solution is to pass additional parameters in SOAP headers utilizing with the help of Custom headers in WCF. A SOAP envelope contains a header and a body. Method call and its parameters are transformed to SOAP body whereas SOAP header usually contains application-specific information (like authentication etc.)

 image

A simple way to achieve this in WCF is to add MessageHeader in your proxy class as in code snippet below:

public partial class TestServiceClient : ClientBase<Client.ServiceProxy.ITestService>, Client.ServiceProxy.ITestService
{
    public TestServiceClient()
    {
        var header = new MessageHeader<string>("Customer Unique Id: 12345");
        var untyped = header.GetUntypedHeader("Identity", "http://www.adilmughal.com");
        OperationContext.Current.OutgoingMessageHeaders.Add(untyped);
    } 
    //Other constructors and Service Method Calls
}

However this is really NOT a suitable approach as if you would be generating proxy using svcutil.exe or using Visual Studio then it will replace your proxy code.

A Better Solution to solve this problem is to utilize custom behavior extension in WCF to pass additional parameters in SOAP Message header. Following are the steps required on client:

1) Implement IClientMessageInspector to create custom message inspector

public class MyMessageInspector : IClientMessageInspector
{
    public void AfterReceiveReply(ref Message reply,object correlationState)
    {
       Console.WriteLine("SOAP Response: {0}", reply.ToString());
    }
        
    public object BeforeSendRequest(ref Message request,IClientChannel channel)
    {
       var header = new MessageHeader<string>("Customer Unique Id: 12345");
       var untyped = header.GetUntypedHeader("Identity", "http://www.adilmughal.com");
       request.Headers.Add(untyped);Console.WriteLine("SOAP Request: {0}", request.ToString());
       return null;
    } 
}

2) Create a custom behavior class implementing IEndPointBehavior and BehaviorExtensionElement. Then add the custom message inspector in runtime in ApplyClientBehavior method as shown in code snippet below:

public class CustomBehavior : BehaviorExtensionElement, IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new MyMessageInspector());
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }

    public override Type BehaviorType
    {
        get {   return typeof(CustomBehavior);  }
    }   

    protected override object CreateBehavior()
    {
        return new CustomBehavior();
    }
}

3) Finally, register behavior in .config under

<behaviors>
 <endpointBehaviors>
 <behavior>
 <customInspector />
 </behavior>
 </endpointBehaviors>
</behaviors>
<extensions>
 <behaviorExtensions>
 <add name="customInspector" type="Client.CustomBehavior, Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
 </behaviorExtensions>
</extensions>

That is all you have to do on client end to pass additional parameter in SOAP header using Custom Behavior in WCF.

To retrieve parameter passed in header on server side, you need to use OperationContext object

MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders;
string customParameter = headers.GetHeader&lt;string&gt;("Identity", "http://www.adilmughal.com");
return string.Format("You entered: {0}", customParameter);

This would achieve the objective. Following is the detail of SOAP Envelope:

SOAP Request:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/ITestService/GetDataAction>
<Identity xmlns="http://www.adilmughal.com">Customer Unique Id: 12345Identity>
s:Header>
<s:Body>
<GetData xmlns="http://tempuri.org/">
<value>123value>
GetData>
s:Body>
SOAP Response:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<GetDataResponse xmlns="http://tempuri.org/">
<GetDataResult>You entered: Customer Unique Id: 12345GetDataResult>
GetDataResponse>
s:Body>
s:Envelope>

In this post we saw how to create custom SOAP header in WCF to pass parameter from client to server using WCF behavior extension. Hope this helps.




Microsoft Application Platform at a Glance

“To stay on the map you’ve got to keep showing up.” — Peter Gallagher

Periodically I create a map of the Microsoft application platform. Making the map helps me stay on top of the platform, identify potential changes to architecture and design strategies, and anticipate trends.  It also helps me figure out where to invest my time and energy.  It also helps me see potential customer confusion.

Here is my latest map of the Microsoft application platform by category:

Application Infrastructure

  • .NET Framework

  • Base Class Libraries (BCL)

  • Common Language Runtime (CLR)

  • Language Integrated Query (LINQ)

ALM (Application Life-Cycle Management)

  • Visual Studio Team System
  • Visual Studio Team Foundation Server

App Frameworks / Extensions

  • Enterprise Library
  • Managed Extensibility Framework (MEF)

Cloud

  • Windows Azure
  • Windows Azure DataMarket (“Dallas”)
  • Windows Azure Tools for Microsoft Visual Studio
  • App Fabric
  • SQL Azure

Collaboration / Integration / Workflow

  • Windows Workflow Foundation (WF)
  • Microsoft Office SharePoint Server (MOSS)
  • Microsoft BizTalk Server

Data Access

  • ADO.NET Core
  • ADO.NET Entity Framework
  • ADO.NET Sync Framework
  • LINQ to SQL
  • OData
  • WCF Data Services
  • WCF RIA Services

Database Server / Storage

  • SQL Azure
  • SQL Server
  • SQL Server Compact

Desktop

  • WPF (Windows Presentation Foundation)
  • Silverlight (Out-of-Browser)
  • Windows Forms

Developer Tools

  • Microsoft Visual Studio
  • Microsoft Expression Studio
  • Microsoft Visual Studio Express
  • Microsoft Visual Studio LightSwitch
  • Microsoft Visual Studio Team Foundation Server

Games

  • XNA
  • D3D
  • Win32

Identity

  • WIF (Windows Identity Foundation) (Geneva)
  • Active Directory Federation Services (Geneva Server)
  • Card Space

Languages

  • Common Language Runtime (CLR)
  • Dynamic Language Runtime
  • Visual Basic
  • Visual C#
  • Visual C++
  • F#
  • Iron Python
  • IronRuby

LINQ

  • LINQ to Entities
  • LINQ to SQL
  • LINQ to XML
  • LINQ to DataSet
  • LINQ to Objects

Manageability

  • Systems Center Operations Manager (SCOM)

Office

  • Office 2010
  • Visual Studio Office Development Projects
  • Office 2010 PIA (Primary Interop Assemblies)

Parallel

  • F#
  • Parallel Extensions for .NET
  • PLINQ
  • Task Library

Phone

  • Silverlight for Windows Phone
  • XNA Framework
  • Windows Phone Developer Tools

Services

  • Windows Communication Foundation (WCF)
  • WCF Data Services (ADO.NET Data Services, Astoria)
  • WCF Web APIs
  • WCF RIA Services
  • ASP.NET Web Services (ASMX)

SharePoint

  • SharePoint Server

Web

  • ASP.NET Web Forms
  • ASP.NET Web Pages (WebMatrix)
  • ASP.NET MVC
  • Silverlight
  • CSS
  • HTML / HTML 5.0
  • Internet Explorer
  • JavaScript (Jscript) / JavaScript (as of IE 9)

Web Server

  • Internet Information Services (IIS)
  • IIS Express
  • Web Farm Framework

Windows Server

  • Windows Server
  • Windows Server App Fabric (Dublin + Velocity)

This post is taken from http://blogs.msdn.com/b/jmeier/

Some more fun with Visual Studio 2010 – Part II

In last post we saw few good enhancements in VS 2010. In this post we will explore some exciting new capabilities for Architects in Visual Studio 2010 Ultimate.

If you are using Visual Studio 2010 Ultimate, you will notice Architecture Menu on top. This menu gives architects plenty of options, from modeling their solutions to generating dependencies among your existing projects and the best part of it is that it allows you to even validate your code based on model diagram (H). BUT! for today! We will cover “Generate Dependency Graph” feature in this post.

The primary advantage of generating dependency graph is to visualize your existing software. This is particularly important in scenarios where you are working in an existing software and want to dig dependencies among assemblies/namespaces/classes etc. We know one thing that software are becoming more complex with time and therefore we need better tools and technologies to understand those complex software solutions.

So lets go ahead and give this feature a try!

If we select the option of Generate Dependency Graph –> By Assembly, after few seconds of processing it will show you some kind of web 🙂

dependency graph

The lines depicts the dependency of one assembly to another and the bold lines shows higher number of references or more dependency on other assembly. You can also expand or collapse these assemblies. Interestingly if you double click on any line (representing reference and dependency), It will gives you further option to select the level of detail between two assemblies as shown in image below:

If we select to include Assemblies and Methods , then it will show detail level diagram with assembly containing Methods and their dependency on other assembly’s methods. Cool isn’t it? 🙂

So if you are working on an existing software and you want to understand the code and interaction of different projects and classes, this feature is a real blessing for you 🙂