Body is a Stream
I've answered this question before but it continues to keep being asked so I'll answer it again. This comes up most often when someone is trying to log messages, either through the official message logging feature or on their own by calling ToString.
Why do I get this text rather than the body of the message?
<s:Body>... stream ...</s:Body>
Logging can only display the data that is actually present for a message. Message headers and properties are always buffered but the body content of a message can be either buffered or streamed. If the body content is buffered, then it can easily be played multiple times and so it is displayed while logging. If the body content is streamed, then the data may not be present and it may not be possible to replay the data again in the future. Streamed messages do not attempt to display the body contents to avoid these problems.
If you want to guarantee that you are reading the complete contents of a message, then you have to suck all of the message contents out using a reader or writer yourself. I've seen people recommend calling CreateBufferedCopy as a workaround but this just happens to work with the common implementations of Message today. There's no guarantee that the messages you create from a MessageBuffer are going to be buffered rather than streamed.
Next time: Controlling HTTP Caching
Comments
- Anonymous
October 17, 2007
Hi, just for clarification (I guess these have been answered a gazillion times): I am writing a store and forward intermediary which can also multiplex messages to multiple destinations (with WCF 3.0, in case that was unclear):
- The buffer I get with CreateBufferedCopy always contains an in memory copy of the whole message? (yeah, that might be the reason why you named the method that way)
- what is the most performant way to forward a message to multiple destinations and how expensive is the CreateBufferedCopy/CreateMessage roundtrip?
- I want to do routing based on headers and content of the message - possibly using XPath expressions. I have been using the builtin XPathMessageFilterTable for that. Does that always work (also for streamed messages) and are there any caveats to this solution?
- What is the recommended way of turning a MessageBuffer into a string (the xml representation)?
Anonymous
October 17, 2007
Hi Daniel, CreateBufferedCopy does not promise whether the message will be in memory. The implementation details depend on the channel that created the message. The channels shipping in WCF 3.0 will keep a copy in memory. Because of this the expense of CreateBufferedCopy will vary between implementations. However, the expectation is that this will be the fastest mechanism available. Channel implementers can optimize this operation. For your other question, the XPath engine in System.Xml buffers messages to evaluate expressions.Anonymous
October 17, 2007
A common corner-case in programming is what happens when multiple operations are attempted at the sameAnonymous
October 19, 2007
Is this a good solution to prevent logging ? As logging can easily be activated through app.exe.config (Security reason)Anonymous
October 19, 2007
Hi Camille, I wouldn't think of this as a way to prevent logging. You can't stop people from getting access to the messages if they control the machine and can edit app.config. At an intermediary node you can prevent people from understanding the message contents even if they control the machine by using encryption with message security.