How does WCF Message.ToString() method work?

All of the methods on System.ServiceModel.Channels.Message only allow you to read the message body once, and fail with an exception if called after the message has been read. The msdn documentation confirms that it is only possible to read a message body one. However, if you call ToString() on an already read message, you appear to get back the entire soap envelope, body and all.

So in my case it would seem to be possible to access the body even after it has been read if only the methods would allow it.

Is there something I'm missing here? Is using ToString() as a work-around to get the body not reliable in some situations?

In my case, I'm working on some error logging for some WCF operations and an getting the original message from OperationContext.RequestContext.RequestMessage. I'm logging the message with ToString() because that is the only way I can find to allow me to log the message body.

Answers


ToString may print the message body, but that's not guaranteed. There are many types of Message objects (it's an abstract class). Some of them buffer the whole body, while others only have a forward-only reader over it. The message implementations which buffer the message may write the body when ToString is called, and that's what you're seeing. But this is not guaranteed for all message types. In many cases, the body is simply written as "...stream..." when ToString is called.


Just wanted to share that I have used the message.toString method with success for the purpose of preserving a base64 encoded string derived from a byte[] that is lost when a message buffer is created (the buffer is the only way to make a copy of the original message, so it was required in my code). After creating a buffer, using it to make XML, and editing the XML, I restored the base64 string using the string saved from the toString method. I would not recommend doing it this way, but it really was the only option in this case and I know that it will work in my particular code. That said, I generally think it should be a last resort option.


You should create message copy then read. For example:

using (MessageBuffer messageBuffer = message.CreateBufferedCopy(Int32.MaxValue))
{
    Message restoredMessage = messageBuffer.CreateMessage();
    message = messageBuffer.CreateMessage();
    return MessageToString(ref restoredMessage);
}

RequestContext.RequestMessage is absent on one way call, so ToString will not work, on other way RequestMessage.ToString() will return message content in a string


Need Your Help

How to run some but not all tests in a Perl test suite in parallel?

perl testing parallel-processing automated-tests

I've got a Perl-based test suite with 10,000+ tests that I would like to make run faster. I've tested using the -j flag to prove, and I have found that most-but-not-all of my tests are ready to run...

Uploading Free app and Paid app to Apple AppStore

ios app-store itunesconnect

I've searched for this question but I couldn't find the answer for it anywhere that's why I'm asking it here please bear with me.