views:

62

answers:

3

I send a handful of identical (except for Id#, obviously) messages to an MSMQ queue on my local machine. The body of the messages is a serialized XElement object.

When I try to process the first message in the queue, I am able to successfully de-serialize the Message.Body object and save it to file. However, when trying to process the next (or any subsequent) message, the Message.Body is absent, and an exception is thrown. I have verified the Message ID's are correct for the message attempting to be processed.

The XML being serialized is properly formed.

Any ideas? I am basing my code on the Microsoft MSMQ Book order sample found here: http://msdn.microsoft.com/en-us/library/ms180970%28VS.80%29.aspx

// Create Envelope XML object
        XElement envelope = new XElement(env + "Envelope", new XAttribute(XNamespace.Xmlns + "env", env.NamespaceName) <snip>            

//Send envelope as message body
          MessageQueue myQueue = new MessageQueue(String.Format(@"FORMATNAME:DIRECT=OS:localhost\private$\mqsample"));

          myQueue.DefaultPropertiesToSend.Recoverable = true;

          // Prepare message 
          Message myMessage = new Message();
          myMessage.ResponseQueue = new MessageQueue(String.Format(System.Globalization.CultureInfo.InvariantCulture,
                @"FORMATNAME:DIRECT=TCP:192.168.1.217\private$\mqdemoAck"));
          myMessage.Body = envelope;

          // Send the message into the queue.
          myQueue.Send(myMessage,"message label");

//Retrieve messages from queue            
        System.Messaging.Message message = mqOrderQueue.Receive();

The Message.Body value I see on the 1st retrieve is as expected: <?xml version="1.0" encoding="utf-8"?> <string>Some String</string> However, the 2nd and subsequent retrieve operations Message.Body is: "Cannot deserialize the message passed as an argument. Cannot recognize the serialization format."

How does this work fine the first time but not after that? I have tried message.Dispose() after retrieving it but it did not help.

Thank you very much for any help on this!

A: 

If you receive the first message and then load the management console to look at the queue and you can see the bodies in the properties dialog for those messages then that might indicate that you're never actually persisting a body for them. Maybe?

I've never had any problems doing a receive by ID on MSMQ, although I know that in some high-load scenarios under distributed transactions it does have a bug or two that cause threads to get stuck waiting.

Then again receiving by ID sort of defeats the point of a queue so I never did use that much :D

kprobst
Thank you for the prompt reply. In the management console, all messages are verified to be in the queue. On any Receive operation, whether the body is read successfully or not, the message is in fact removed from the queue (as verified with mgmt console).Also, I edited my post to reflect the change to just .Receive(); the problem persists even when doing it this way.
Andrew A
Ah, so `Receive()` does not work either? Are you 100% sure that those messages have a body? I know you mentioned that you checked that the _messages_ are there, which is fine, but bring up the properties dialog for one of them and see if there is indeed a body there. I'd be surprised that this is a bug with MSMQ, you are doing pretty standard stuff here as far as I can see.
kprobst
I am positive the messages have a body. Check it out:http://imgur.com/BuDTv.jpgEach message in the queue is like this as viewed with Computer Management. I agree it seems very odd since the first body is read fine. After that point every ID is read but not the body.
Andrew A
A: 

Maybe the second body does not contain the XML preamble, because an object is still around that thinks it already wrote it? In other words, you might have some state that needs to be cleaned up somewhere.

I recommend looking at the messages in the console as kprobst suggested.

Paul Williams
A: 

I was able to resolve this problem by creating a new object, and assigning my serialized "envelope" as an object inside of the new object (instead of assigning my "envelope" directly to Message.Body.

//Class to create new message object
public class MsgToDB
{
    public int someInteger;
    public DateTime timeStamp;
    public XElement payload;
}

// Create an object of class MsgToDB which will contain envelope object 
MsgToDB testMsgObj = new MsgToDB();
testMsgObj.someInteger = 3;
testMsgObj.timeStamp = DateTime.Now;
testMsgObj.payload = envelope;

// Create and send message
Message testMsg = new Message(testMsgObj);
myQueue.Send(testMsg, "message label");

Thank you all for the helpful advice.

Andrew A