This message cannot support the operation because it has been copied
Has this error message happened to you? It's because the lifetime of a message only lasts for one use. Once you've looked at the contents of a message, or copied the contents somewhere, you can't read the message again. This is a common problem encountered when people are trying to write a message inspector. Since you're expected to pass the message along after you're done inspecting it, it's quite likely that you'll need to make a new copy of the message. If you don't make a copy of the message, then the next person will have nothing to read.
This means that your message inspector code should look something like this:
public void AfterReceiveReply(ref Message reply, object correlationState)
{
MessageBuffer buffer = reply.CreateBufferedCopy(MaxMessageSize);
// Do something with the copied message
reply = buffer.CreateMessage();
buffer.Close();
}
Comments
Anonymous
July 26, 2006
How about "Please try again in 0 seconds" Classic.Anonymous
July 26, 2006
The comment has been removedAnonymous
July 26, 2006
We don't automatically copy the message because that's an expensive operation and we don't like doing expensive things behind your back. Copying the message for you might require taking up gobs of memory or silently buffering streams. Instead of explaining why you get this error message, we'd have to explain why your performance is so bad. That's much harder to diagnose just from hearing the symptoms.Anonymous
July 26, 2006
Fair enough about the explicitness, but the current implementation - having the Message passed explicitly as 'ref' - just screams "you can modify the Message object and it will stick". Any way to make it more obvious from the code itself - not just the documentation - that this is what's happening?Anonymous
July 26, 2006
It would have been nice to be clearer here. The name MessageInspector is confusing because this extensibility point does a whole lot more than let you "inspect" messages, which is why we can't do much to automate the process. The problem is general to all users of the Message class though. Custom channel authors have to deal with the same issue. We might be able to create a new message implementation in the future to solve this.Anonymous
July 26, 2006
How about changing the the name of the incoming Message parameter from "reply" to "singleUserReplyObject", or something less atrocious but which still conveys the fact that once touched this object is dead?Anonymous
July 26, 2006
And another question (sorry for the harassment): I noticed that we're copying the message into a buffer, and then recreating the message from that buffer. My question is about your " // Do something with the copied message" comment - you mean with the original message, right?Anonymous
July 27, 2006
"Do something with the copied message" means do something with the copy in the message buffer. We can't do anything further with the original message, it's already been copied. Unlike a message, you can use a message buffer more than once.Anonymous
July 29, 2006
But the buffer is just that - an untyped byte buffer. To do something with it, I have to creat a temporary Message from the buffer, right?
I'm trying to think of a good balance here between explicitness (having the user aware of the buffer copy and the Message creation step) and being convenient/non-verbose (not requiring two distinct steps for a common operation like creating a copy of a message)Anonymous
August 07, 2006
I've mentioned that messages have a definite lifecycle without ever mentioning what the lifecycle represents....Anonymous
February 19, 2007
I haven't forgotten about the goal to put together a table of contents for all of these articles. TheAnonymous
January 10, 2008
How do I use a field in the message to answer an authorization request in ServiceAuthorizationManager?