Tuesday, April 12, 2011

Read XML from MemoryStream

This illustration of this example follows the previous post. What if we want to generate XML into a stream instead of a physical file? Initially, I thought the solution was very simple and could be done in a minute. Instead, it took me hours to figure out.

    public MemoryStream ToXml() {
      MemoryStream ms = new MemoryStream();
      
      XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
      ns.Add("", "");    

      XmlSerializer ser = new XmlSerializer(typeof(Subscribers));      
      ser.Serialize(ms, new Subscribers(), ns);       
 
      return ms;
    } 

If you read the XML from the MemoryStream returned by the above code with XDocument or XmlDocument, you will encounter "Root element is missing" error. For example,

  using (StreamReader reader = new StreamReader(new Subscribers().ToXml())) {
    subscribers = XDocument.Load(reader);
  }

When the XmlSerializer has finished the "write" into the MemoryStream, the stream pointer will be at the end of the XML structure. Thus, the function should rewind the pointer to the beginning of the stream before returning the MemoryStream to the caller. Using ms.Seek(0, SeekOrigin.Begin); . before the statement return ms; will do the trick.

    public MemoryStream ToXml() {
      MemoryStream ms = new MemoryStream();
      
      XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
      ns.Add("", "");    

      XmlSerializer ser = new XmlSerializer(typeof(Subscribers));      
      ser.Serialize(ms, new Subscribers(), ns);       
      
      ms.Seek(0, SeekOrigin.Begin);  // rewind the pointer the top of the stream

      return ms;
    } 

1 comment: