Search code examples
c#vb.netexceptionmsmqpeek

MSMQ .Net 2.0 Peek vs Receive


MSMQ is set up on server running Windows 2003 R2 SP 2. .Net 2.0 is installed. All messages being sent to this queue are supposed to be of type QMsg. Regardless, Peek returns an object of type System.Messaging.Message BUT the Body is erroring with an exception that indicates the Root is missing. I have set the breakpoint at the 'This' definition and can peer into the 'Something' instance.

Body = {"Cannot deserialize the message passed as an argument. Cannot recognize the serialization format."}

public QMsg GetCommand()
{
    Message Something = mqCompany.Peek();
    string This = Something.Body.GetType.ToString.ToLower;
    //. . . Code to check the type of Body
    return (QMsg)mqCompany.Receive().Body;
}

Private Function GetCommand() as QMsg
    Dim Something as Message = mqCompany.Peek()
    Dim This as string = Something.Body.GetType.ToString.ToLower
    . . . Code to check the type of Body
    GetCommand = CType(mqCompany.Receive().Body, QMsg)
End Function

If I allow the 'This' statement to execute, it throws the exception. However, if I skip to the final statement, which contains the Receive method, it executes just fine. The strangest thing is that once the Receive is executed once, the Peek will work on everything after that. Is there something special I need to do before executing Peek initially?


Solution

  • When you read from Message.Body property, .Net will try to deserialize it and create object. By default, object deserialization is performed using XMLMessageFormatter. That message you got suggests that body was originaly serialized some other way, perhaps using BinaryMessageFormatter or not sent from .Net at all.

    In order to solve this, you must take a look at sending side, check which formatter is used there and configure it same for receiving. Also, if XMLMessageFormatter is used, you must set its TargetTypes or TargetTypeNames property when receiving.

    It's also possible that message is not .Net serialized object at all. In that case, you can use BodyStream property to directly access body byte by byte and decode it any way you have to.

    For this issue it's entirely irrelevant whether you use Peek or Receive. Messages body will be handled same way.