Reputation:
I am trying to modify response from a Web Service using a ClientMessageInspector. At some point I need to create a Message
from a modified XMLStream
. The content of the stream is below:
<soapenv:Envelope xmlns:soapenv="http://env" xmlns:xsd="http://xsd" xmlns:xsi="http://xsi" xmlns:v1="http://v1">
<soapenv:Body>
<v1:VM>
<SH>
<a>aa</a>
<b>bb</b>
</SH>
</v1:VM>
</soapenv:Body>
</soapenv:Envelope>
I try to create the message using:
System.Xml.XmlReader XMLReader = System.Xml.XmlReader.Create(XMLStream);
Message ModifiedReply = System.ServiceModel.Channels.Message.CreateMessage(OriginalReply.Version, null, XMLReader);
However when I print the Message content with Message.ToString() I get:
<s:Envelope xmlns:s="http://env">
<s:Header />
<s:Body>
... stream ...
</s:Body>
</s:Envelope>
How can I prevent "...stream..." and get the actual XML parts?
Upvotes: 3
Views: 1301
Reputation: 87308
A message when created from a XmlReader
will always print out ...stream...
as its body. Since the reader is a forward-only view on the underlying XML, it cannot be consumed multiple times, so if ToString
were to read the data from the reader, the message wouldn't be able to be used by the rest of the WCF pipeline (such as the encoder, which would write it to the wire).
What you can do, if you really want to see the full message, is to buffer the message yourself, then recreate it later. You can use a MessageBuffer
for that. And if you really want the full message contents, ToString
may or may not give it to you, so you need to write the message out to force it to be printed.
public class StackOverflow_12609525
{
public static void Test()
{
string xml = @"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/""
xmlns:xsd=""http://xsd""
xmlns:xsi=""http://xsi""
xmlns:v1=""http://v1"">
<soapenv:Body>
<v1:VM>
<SH>
<a>aa</a>
<b>bb</b>
</SH>
</v1:VM>
</soapenv:Body>
</soapenv:Envelope>";
MemoryStream XmlStream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
XmlReader reader = XmlReader.Create(XmlStream);
Message originalReply = Message.CreateMessage(reader, int.MaxValue, MessageVersion.Soap11);
Console.WriteLine(originalReply); // this shows ...stream...
Console.WriteLine();
XmlStream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
reader = XmlReader.Create(XmlStream);
Message modifiedReply = Message.CreateMessage(reader, int.MaxValue, originalReply.Version);
MessageBuffer buffer = modifiedReply.CreateBufferedCopy(int.MaxValue); // this consumes the message
Message toPrint = buffer.CreateMessage();
MemoryStream ms = new MemoryStream();
XmlWriterSettings ws = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
OmitXmlDeclaration = true,
Encoding = new UTF8Encoding(false)
};
XmlWriter w = XmlWriter.Create(ms, ws);
toPrint.WriteMessage(w);
w.Flush();
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
modifiedReply = buffer.CreateMessage(); // need to recreate the message here
}
}
Upvotes: 3