Reputation: 81884
I am receiving an XML via an HttpPost to my service, and I want to log the received value for debugging purposes.
First I deserialize it into an entity like this:
XmlSerializer s = new XmlSerializer(typeof(TransactionResults));
TransactionResults t = (TransactionResults)s.Deserialize(stream);
This, of course, moves the stream to the end, so then I cannot log the original value.
I tried seeking to the beginning to then read it with a StreamReader
, but it throws a NotSupportedException
As a test, I tried re-serializing it (I created all the objects again to avoid re using them to see if that was the problem)
private static string GetContents(TransactionResults t)
{
XmlSerializer s = new XmlSerializer(typeof(TransactionResults));
MemoryStream stream = new MemoryStream();
s.Serialize(stream, t);
return new StreamReader(stream).ReadToEnd();
}
This method returns an empty string.
(Obviously, if I invert the logic, the value gets logged, but then I cannot get the object)
What am I doing wrong? What would be the best way to deserialize the value into an object and log it as a string?
Upvotes: 1
Views: 180
Reputation: 10330
This is the method I use when I need to get a Xml string from an XML serializable Object. So you first deserialize the object as you have been and then you get the string from the object, you will now have both the string and the original object.
public static string ToXmlString(object xmlObject)
{
if (xmlObject == null)
throw new NullReferenceException("xmlObject cannot be null.");
String xmlResult = null;
XmlSerializer serializer = new XmlSerializer(xmlObject.GetType());
using (StringWriter writer = new StringWriter())
{
serializer.Serialize(writer, xmlObject);
xmlResult = writer.ToString();
}
return xmlResult;
}
Upvotes: 0
Reputation: 1499860
You should be able to seek to the beginning of a MemoryStream
with no issues:
private static string GetContents(TransactionResults t)
{
XmlSerializer s = new XmlSerializer(typeof(TransactionResults));
MemoryStream stream = new MemoryStream();
s.Serialize(stream, t);
stream.Position = 0; // Rewind to the beginning of the stream
return new StreamReader(stream).ReadToEnd();
}
If you want to log the original data instead, you'll effectively need to copy it into a MemoryStream
to start with - then you can rewind it as often as you like.
I find it's useful to have a method like this to exhaust one stream, writing to another:
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[8 * 1024];
int len;
while ( (len = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, len);
}
}
You can call that passing in your service's input stream as the input, and a new MemoryStream
as the output.
Upvotes: 4
Reputation: 64467
Read the stream into a memory stream and operate on that, it supports seeking.
Upvotes: 0