views:

55

answers:

2

After writing and reading an xml string to and from a stream, it ceases to be deserializable. The new string is clipped.

string XmlContent = getContentFromMyDataBase();
XmlSerializer xs = new XmlSerializer(typeof(MyObj));
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
char[] ca = XmlContent.ToCharArray();      // still working up to this point.
ms.Position = 0;
sw.Write(ca);
StreamReader sr = new StreamReader(ms);
ms.Position = 0;
string XmlContentAgain = sr.ReadToEnd();
Console.WriteLine(XmlContentAgain);        // (outputstring is too short.)
MyObj theObj = (MyObj)xs.Deserialize(ms);  // Can't deserialize.

Any suggestions as to how to fix this or what is causing the problem? My only guess is that there is some form of encoding issue, but I wouldn't know how to go about finding/fixing it.

Additionally, myObj has a generic dictionary member, which typically isn't serializable, so I have stolen code from Paul Welter in order to serialize it.

A: 

You need to Flush or Close (closing implicitly flushes) the StreamWriter, or you cannot be sure it is done writing to the underlying stream. This is because it is doing some internal buffering.

Try this:

using(StreamWriter sw = new StreamWriter(ms)) 
{
    char[] ca = XmlContent.ToCharArray();      // still working up to this point.
    ms.Position = 0;
    sw.Write(ca);
}
StreamReader sr = new StreamReader(ms);
ms.Position = 0;
string XmlContentAgain = sr.ReadToEnd();
driis
This doesn't work. The stream becomes inaccessible after the using block. Moving the code from outside to inside results in the same problems as before.
That is because disposing StreamWriter also disposes the underlying object. You can get the buffer from the stream, or you can call Flush on your writer instead of disposing it.
driis
+2  A: 

Try flushing and disposing or even better simplify your code using a StringReader:

string xmlContent = getContentFromMyDataBase();
var xs = new XmlSerializer(typeof(MyObj));
using (var reader = new StringReader(xmlContent))
{
    var theObj = (MyObj)xs.Deserialize(reader);
}

Note: The getContentFromMyDataBase method also suggests that you are storing XML in your database that you are deserializing back to an object. Don't.

Darin Dimitrov
Why wouldn't you store XML in a database?
Mark
Because a SQL database is relational. XML is hierarchical. They are not compatible. Database is for storing data, not for storing representation of the data (which is XML).
Darin Dimitrov
XML is text. Databases are very good at storing text. It's entirely appropriate to store XML in a database. Your distinction between "data" and "representation of the data" is arbitrary and meaningless.
Mark
@Mark, I have to disagree with you. XML itself can be seen as a database for storing data, but storing database inside another database seems wrong to me.
Darin Dimitrov
The xml is stored in the database, as text.
@user420667, I know that XML is stored as text. That's the problem. You are not storing the data this XML contains in different columns such as FirstName, LastName, but putting everything in a single database column. How are you performing indexing this data? How are you searching inside it? Too many problems in storing XML in database.
Darin Dimitrov
@Darin: A text file can be seen as a database for storing data. A string, by extension, can be seen as a database for storing data. A number can be seen as a database for storing data. It's all just data. Databases store data, that's what they do. A database may be "relational", but that only refers to HOW it stores data, not WHAT data may be stored inside it. You can relationally store hierarchical data. People have been doing it since relational databases were invented.
Mark
@Mark, how are you searching this XML *data*? For example find all records that in its XML column contain a tag `FirstName` that starts with the letter `A`? I agree that everything is data. But a database is not for just storing anything inside. It's the ease of querying as well.
Darin Dimitrov
@Darin: How do you know that indexing and searching need to be performed on the XML data? It seems to me that you're making a lot of unfounded assumptions. Even if the XML did need to be indexed, some database engines (MSSQL) provide special indexes that can index XML content in database fields.
Mark
@Darin: As Mark has alluded to, MS SQL Server has a specific data type just to hold XML. It can query the XML and will even index it, depending on your schema. Storing XML in the database does run into some tension between relational and document-based approaches, but it's hardly evil.
Steven Sudit
@Mark, I know, as the OP tries to deserialize this data back to a .NET object in order to perform some querying, processing, etc... on it while this can perfectly be made by the database.
Darin Dimitrov
Well, the code works now, thanks. For my purposes it suffices to put the data in as Xml, which can later be loaded and browsed in say internet explorer. If it weren't for the browsing thing, I wouldn't have added it as XML.
@Darin: I've posted a new community wiki question at http://stackoverflow.com/questions/3524423/what-are-the-common-issues-surrounding-storage-of-xml-data-in-a-relational-databa if you'd like to continue/expand upon the discussion.
Mark
@Mark, I've already expressed my opinion on the subject and hate repeating myself. I don't store XML data in a database unless of course it is a file attachment, code snippet or something that should be used as is.
Darin Dimitrov