Infosys Microsoft Alliance and Solutions blog

« User Settings Persistence in .Net 2.0 | Main | What's in a class/method name? »

Finding deserialization problems when using MSMQ with WCF

I was trying to build a sample that had a WCF service consuming an input message from MSMQ. Post writing the necessary code when I ran the service and waited for it to pick up the message from MSMQ, nothing happened.

The message was not getting picked up and I wasn't get any exception or an error logged in event log. I didn't know what to do. Since I had used a transactional queue, and the message continued to sit there, I knew this meant that something went wrong while reading the message, but what?

It turns out that there is a way we can get some insight into what went wrong. If there is any other way than what I descibe below, I would love to hear about it.

If one is working with inline with the samples, the typical code for console based service host will look as below

using (ServiceHost serviceHost = new ServiceHost(typeof(MyMSMQService)))
{
    serviceHost.Open();

    // The service can now be accessed.
    Console.WriteLine("The service is ready.");
    Console.WriteLine("Press <ENTER> to terminate service.");
    Console.ReadLine();
}

A little change to this code is what is required to get insight into what's going wrong. The modified code will look like below

using (ServiceHost serviceHost = new ServiceHost(typeof(MyMSMQService)))
{
    serviceHost.Faulted += new EventHandler(serviceHost_Faulted);

    serviceHost.Open();

    // The service can now be accessed.
    Console.WriteLine("The service is ready.");
    Console.WriteLine("Press <ENTER> to terminate service.");
    Console.ReadLine()
}

static void serviceHost_Faulted(object sender, EventArgs e)
{
    Console.WriteLine("Service has faulted");
}

Essentially I have added an event handler to handle the Service Faulted event. This by itself however doesn't give any additional information. However you can put a break point in the event handler and when a fault occurs, the Locals debug window in Visual Studio shows an additional local variable - $exception, and this shows the required details of what went wrong.

In my case, this clearly showed that the problem had happened while trying the deserialize the message from MSMQ. It couldn't be deserialied since the type wasn't known. This meant that the type I had declared didn't match with what was there in the input message and I was then able to resolve the problem.

A few tips when working with msmqIntegrationBinding and WCF

  1. Ensure the type you have defined as the input parameter is marked Serializable
  2. Decorate the Service as - [ServiceKnownType(typeof(<yourType>))]
  3. Good practice to decorate the Interface method as - [OperationContract(IsOneWay = true, Action = "*")]
  4. Tab the service method implementation as - [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
  5. Set receiveErrorHandling ="Fault" in the binding details for msmqIntegrationBinding if you want to get fault information. Setting this to "Drop" will just drop the message and you won't know what really happened. Refer to msmqIntegrationBinding documentation for more details

Transaction requirements will ofcourse depend on your application needs, but note that if the queue isn't set as transactional, in case of errors, there will be no way to recover the message since it will be deleted from the queue while reading.

Comments

You sure about the exception local showing up in the Faulted event? I don't see it when my event handler for the Faulted event gets invoked. Am I missing something?

@Jason, if you just run the code and try to catch the exception, it doesn't come. I saw it when i put a breakpoint inside the handler and then checked the locals windows in the debbuger.

If no exception is raise, you may not see anything.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Please key in the two words you see in the box to validate your identity as an authentic user and reduce spam.

Subscribe to this blog's feed

Follow us on

Blogger Profiles

Infosys on Twitter