Silverlight Object Binary Serialization to Database - c#

Right now I am programming a multiplayer card game in Silverlight
I am wondering how to store a object best binary in a sql database.
I have a GameState Object which contains the current state of a game between two players. I want to store this object in a sql database that both player can access and change it anytime.
How would you do that with Silverlight + RIA Services? Especially the part where you serialize the object in Silverlight.
Thanks

I would do the serialization on the server side. Add an Invoke operation to your RIA services domain context that accepts your GameState object. On the server side you can then use standard .NET serialization (personally I would recommend XML serialization instead of binary, but it shouldn't matter).

First, you can not possibly simply serialize something at the server. It must be serialized before it can be sent to the server. But it seems that perhaps you are making things too complicated/magical.
Given what you have said, I would start with by defining my GameState object (and any other object you need) inside the Entity Framework. Include any and all fields that are needed to save the state of the game. Then you should be able to have the framework create the needed tables.
Once you have done this, add a DomainService to the web project and when you compile the objects will then be available inside your Silverlight project.

Finally i decided to use XML serialization.
I found a great article about XML Serialization: http://www.ingebrigtsen.info/post/2008/11/29/Serialization-in-Silverlight.aspx
That's how it looks like in my Silverlight code:
public static class MySerializer
{
public static string Serialize<T>(T data)
{
using (var memoryStream = new MemoryStream())
{
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(memoryStream, data);
memoryStream.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(memoryStream);
string content = reader.ReadToEnd();
return content;
}
}
public static T Deserialize<T>(string xml)
{
using (var stream = new MemoryStream(Encoding.Unicode.GetBytes(xml)))
{
var serializer = new DataContractSerializer(typeof(T));
T theObject = (T)serializer.ReadObject(stream);
return theObject;
}
}
}

I've found the SharpSerializer package very easy to use for fast binary serlization in Silverlight: http://www.sharpserializer.com/en/index.html

Related

Dispose IRandomAccessStream after DataPackage.SetData or DataPackage.GetDataAsync?

Consider putting data onto a windows clipboard DataPackage using SetData and later retrieving it using GetDataAsync, like this:
IEnumerable<T> objects = ...;
var randomAccessStream = new InMemoryRandomAccessStream();
using (XmlDictionaryWriter xmlWriter = XmlDictionaryWriter.CreateTextWriter(randomAccessStream.AsStreamForWrite(), Encoding.Unicode)) {
var serializer = new DataContractSerializer(typeof(T), knownTypes);
foreach (T obj in objects) {
serializer.WriteObject(xmlWriter, obj);
}
}
dataPackage.SetData(formatId, randomAccessStream);
Then later on (e.g. in Clipboard.ContentsChanged),
randomAccessStream = await dataPackageView.GetDataAsync(formatId) as IRandomAccessStream;
xmlReader = XmlDictionaryReader.CreateTextReader(randomAccessStream.AsStreamForRead(), Encoding.Unicode, XmlDictionaryReaderQuotas.Max, (OnXmlDictionaryReaderClose?)null);
var serializer = new DataContractSerializer(typeof(T), knownTypes);
while (serializer.IsStartObject(xmlReader)) {
object? obj = serializer.ReadObject(xmlReader);
...
}
xmlReader.Dispose(); // in the real code, this is in a finally clause
The question I have is, when do I dispose the randomAccessStream? I've done some searching and all the examples I've seen using SetData and GetDataAsync do absolutely nothing about disposing the object that is put into or obtain from the data package.
Should I dispose it after the SetData, after the GetDataAsync, in DataPackage.OperationCompleted, in some combination of these, or none of them?
sjb
P.S. If I can squeeze in a second question here ... when I put a reference into a DataPackage using for example dataPackage.Properties.Add( "IEnumerable<T>", entities), does it create a security risk -- can other apps access the reference
and use it?
tldr
The Clipboard is designed to pass content between applications and can only pass string content or a references to files, all other content must be either serialized to string, or saved to a file, or must behave like a file, to be access across application domains via the clipboard.
There is support and guidance for passing custom data and formats via the clipboard, ultimately this involves discrete management around what is "how to prepare the content on the provider side" and "how to interpret the content on the consumer side". If you can use simple serialization for this, then KISS.
IEnumerable<Test> objectsIn = new Test[] { new Test { Name = "One" }, new Test { Name = "two" } };
var dataPackage = new DataPackage();
dataPackage.SetData("MyCustomFormat", Newtonsoft.Json.JsonConvert.SerializeObject(objectsIn));
Clipboard.SetContent(dataPackage);
...
var dataPackageView = Clipboard.GetContent();
string contentJson = (await dataPackageView.GetDataAsync("MyCustomFormat")) as string;
IEnumerable<Test> objectsOut = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<Test>>(contentJson);
In WinRT the DataPackageView class implementation does support passing streams however the normal rules apply for the stream in terms of lifecycle and if the stream is disposed or not. This is useful for transferring large content or when the consumer might request the content in different formats.
If you do not have an advanced need for it, or you are not transmitting file or image based resources, then you do not need to use a stream to transfer your data.
DataPackageView - Remarks
During a share operation, the source app puts the data being shared in a DataPackage object and sends that object to the target app for processing. The DataPackage class includes a number of methods to support the following default formats: text, Rtf, Html, Bitmap, and StorageItems. It also has methods to support custom data formats. To use these formats, both the source app and target app must already be aware that the custom format exists.
OPs attempt to save a stream to the Clipboard is in this case an example of saving an arbitrary or custom object to the clipboard, it is neither a string or a pointer to a file, so the OS level does not have a native way to handle this information.
Historically, putting string data, or a file reference onto the clipboard is effectively broadcasting this information to ALL applications on the same running OS, however Windows 10 extends this by making your clipboard content able to be synchronised across devices as well. The DataTransfer namespace implementation allows you to affect the scope of this availability, but ultimately this feature is designed to allow you to push data outside of your current application sandboxed domain.
So whether you choose serialize the content yourself, or you want the DataTransfer implementation to try and do it for you, the content will be serialized if it is not already a string or file reference format, and that serialized content, if it succeeds, is what will be made available to consumers.
In this way there is no memory leak or security issue where you might inadvertently provide external processes access to your current process memory or execution context, but data security is still a concern, so don't use the clipboard to pass sensitive content.
A simpler example for Arbitrary or Custom data
OPs example is to put an IEnumerable<T> collection of objects onto the clipboard, and to retrieve them later. OP is choosing to use XML serialization via the DataContractSerializer however a reference to the stream used by the serializer was saved to the clipboard, and not the actual content.
There is a lot of plumbing and first principals logic going on that for little benefit, streams are useful if you are going to stream the content, so if you are going to allow the consumer to control the stream but if you were going to write to the stream in a single synchronous process, then it is better to close off the stream altogether and pass around the buffer that you filled via your stream, we don't even try to re-use the same stream at a later point in time.
The following solution works for Clipboard access in WinRT to pre-serialize a collection of objects and pass them to a consumer:
IEnumerable<Test> objectsIn = new Test[] { new Test { Name = "One" }, new Test { Name = "two" } };
var dataPackage = new DataPackage();
string formatId = "MyCustomFormat";
var serial = Newtonsoft.Json.JsonConvert.SerializeObject(objectsIn);
dataPackage.SetData(formatId, serial);
Clipboard.SetContent(dataPackage);
Then in perhaps an entirely different application:
string formatId = "MyCustomFormat";
var dataPackageView = Clipboard.GetContent();
object content = await dataPackageView.GetDataAsync(formatId);
string contentString = content as string;
var objectsOut = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<Test>>(contentString);
foreach (var o in objectsOut)
{
Console.WriteLine(o);
}
The definition of Test, in both the provider and the consumer application contexts:
public class Test
{
public string Name { get; set; }
}
when do I dispose the randomAccessStream?
Only Dispose the stream when you have finished using it, when you have Diposed the stream it will be no longer usable in any other contexts, even if you have stored or passed multiple references to it in other object instances.
If you are talking about the original stream referenced in the SetData() logic then look at this from the other angle, If you dispose too early, the consuming code will no longer have access to the stream and will fail.
As a general rule we should try to design the logic such that at any given point in time there is a clear and single Owner for any given stream, in that way it should be clear who has responsibility for Disposing the stream. This response to a slightly different scenario explains it well, https://stackoverflow.com/a/8791525/1690217 however as a general pattern only the scope that created the stream should be responsible for Disposing it.
The one exception to that is that if you need to access the stream outside of the creating method, then the parent class should hold a reference to it, in that scenario you should make the parent class implement IDisposable and make sure it cleans up any resources that might be hanging around.
The reason that you don't see this in documentation is often that the nuances around the timing for calling Dispose() are out of scope or will get lost in examples that are contrived for other purposes.
Specifically for examples where streams are passed via any mechanism and later used, as with DataPackage, it is too hard to show all of the orchestration code to cover the time in between storing the stream with DataPackage.SetData(...) and later accessing the stream via DataPackage.GetDataAsync(...)
Also consider the most common scenario for DataPackage where the consumer is not only in a different logical scope, but most likely in an entirely different application domain, to include all the code to cover when or if to call dispose should encompass the entire code base for 2 different applications.

How to save ParseObject to disk in .NET

I need to save a list of ParseObjects to disk in C#, and was wondering if anyone had any recommendations on how to achieve this.
I am sure that the Parse .NET SDK has a means of converting ParseObjects to/from JSON since that is the format used during transit to parse server, but I haven't been able to find any public methods to do this :(
Hopefully someone has an answer for what should be an easy question! :)
If you are using Newtonsoft You can do this
var jsonString = JsonConvert.SerializeObject(yourObject);
using (StreamWriter writer =
new StreamWriter("SerializedObject.json"))
{
writer.Write(jsonString);
}
To read the JSON file you can do this
using (StreamReader reader =
new StreamReader("SerializedObject.json"))
{
string jsonString = reader.ReadToEnd();
YourObject ObjectFromJson = JsonConvert.DeserializeObject<YourObject>(jsonString);
}
I think you can use ToString() method for parsing. You override the ToString() method in your Class and write parsing code on it.
For more information you can look into below link
https://msdn.microsoft.com/en-us/library/system.object.tostring(v=vs.110).aspx

Saving & loading data on level selection screen, XML, XNA

I am making a basic platformer, my first ever game. I've run into a bit of a problem. So far the game only has one level, and it is loaded from a .txt file. However I'd like to have a sort of an Angry Birdish world/level selection screen.
The plan is to have an icon for each level visible, but only so far completed levels and the next one accessible. Also for the completed levels the score (stars, whatever) would be displayed under the icon.
I do not wish to load the levels from XML, at least not yet. Only the persistent world data that needs to be read AND written. I assume the easiest way is to load even the formatting of the level selection screen from XML, and not use the method i currently use (text files).
I could do this with text files, I suppose, but I really do not relish the idea of writing and sorting through the file. I then discovered that XML-files should be a bit less problematic in this regard. However additional problem rises from the fact tht I've never ever worked with XML-files before.
Could someone point me in a direction of a tutorial for this sort of things, or some sample you might have come accross that accomplishes at least relatively similar results. I don't expect anyone to do the coding for me, but if you have pointers or time and patience to provide a sample, I'd appreciate it a lot.
After some further digging and fumbling with tutorials for older XNA versions I managed to produce following save/load class:
namespace SaveLoadXML
{
class SaveLoad
{
public LevelInfo Load (int id)
{
LevelInfo level;
// Get the path of the save game
string fullpath = "World.xml";
// Open the file
FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate,
FileAccess.Read);
try
{
// Read the data from the file
XmlSerializer serializer = new XmlSerializer(typeof(LevelInfo));
level = (LevelInfo)serializer.Deserialize(stream);
}
finally
{
// Close the file
stream.Close();
}
return (level);
}
public void Save (LevelInfo level, int id)
{
// Get the path of the save game
string fullpath = "World.xml";
// Open the file, creating it if necessary
FileStream stream = File.Open(fullpath, FileMode.OpenOrCreate);
try
{
// Convert the object to XML data and put it in the stream
XmlSerializer serializer = new XmlSerializer(typeof(LevelInfo));
serializer.Serialize(stream, level);
}
finally
{
// Close the file
stream.Close();
}
}
}
}
Now I started to think, is there a way to target a specific part of the XML-file, or is the writing always just from the start? Almost all of the examples I saw had a condition at the start: if the file exists, delete it and then write.
I assume I could (or even should?) make a list of LevelInfo objects and just load them all at once, as there is no real need to load a single LevelInfo anyway. On the saving however, do I need to load the previous state (old list) and then manipulate the list regarding the certain indexes involved, and then delete te file, and save it again.
This might open an easy way for the system to fail if something goes wrong in the saving or power fails for example. The whole file would be lost or corrupt. I suppose this ould be countered with using back-up file and then checking the integrity of the main file, but now it's starting to feel like quite a mountain to climb for a beginner like me.
Having tried this question on GameDev, I'll just clarify the main question here:
1) Can I save only info about one or two levels in the XML-file containing info for all levels? ie. can I use some indexing to point the write operation to a particular section that would then be overwritten/replaced.
2) If not, is there any way to safely load all info from file, delete file, save all info after modifying it where needed.
After some looking into this Json stuff, I've managed to successfully serialize test level information. However, de-serialization fails as I have a rectangle as a part of the object. Error is as follows:
Error converting value "{X:1 Y:1 Width:1 Height:1}" to type 'Microsoft.Xna.Framework.Rectangle'. Path '[0].Rectangle', line 6, position 46.
class LevelInfo
{
public int ID { get; set; }
public Vector2 Dimensions { get; set; }
public Vector2 Position { get; set; }
public Rectangle Rectangle { get; set; }
public int Stars { get; set; }
public string Text { get; set; }
}
class SaveLoadJSON
{
public static List<LevelInfo> Load()
{
List<LevelInfo> levels = new List<LevelInfo>();
using (StreamReader file = File.OpenText("World.json"))
{
JsonSerializer serializer = new JsonSerializer();
levels = (List<LevelInfo>)serializer.Deserialize(file, typeof(List<LevelInfo>));
}
return levels;
}
public static void Save(List<LevelInfo> levels)
{
if (File.Exists("World.json"))
{
File.Delete("World.json");
}
using (FileStream fs = File.Open("World.json", FileMode.CreateNew))
using (StreamWriter sw = new StreamWriter(fs))
using (JsonWriter jw = new JsonTextWriter(sw))
{
jw.Formatting = Formatting.Indented;
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(jw, levels);
}
}
}
Is there a way to work around this? Preferably a relatively simple way for a simple beginner like me.
Or alternatively, is there a way to omit the rectangle information to begin with, and maybe add it later? If I input nothing to the rectangle, it still is added to Json-file with 0 values. I do need the rectangle info for the drawing.
So here comes the promised answer.
Personally I'd prefer using JSon for storing data, since it's a lot easier to work with than XML, and takes up less storage. What you're going to want to do, is make Data Models of your player, enemy, items, scene objects, etc.
Then, you'll want to JsonConvert.SerializeObject() a parent data model, which will contain all those things.
Save this in any file, and Deserialize it again upon load, and reconstruct all objects from scratch.
Alternatively, just have all properties in the classes you're working with already, be public. That way, JsonConvert will be able to actually serialize the entire model. Keep in mind, if you do this runtime, it will make more of a complete snapshot of the Levels current state. Aka. where the enemies are located, the health remaining and whatever else you may have.
I hope this answers your question.

Small Simple Local Data Store for keeping user settings

I have this tiny C# winforms application that will NOT grow larger in any way.
It's just two input fields and a button.
I want to know if you guys have knowledge of a way to store the values that a user inputs in a local datastore. You may consider 10 records to be a lot of data for this scenario.
Requirements
It shouldn't require any setup from the database side. (table creation, etc)
I should be able to just give it an object and it should store it, I don't want to waste time on that.
The data needs to be fairly easily retrievable.
I want to be able to reuse this thing for every small app I create like this.
My Ideas
A POCO object that will be XML-Serialized and saved to the Local Settings folder. Upon loading of the app, this file is deserialized back into the POCO object.
An OODBMS: I have no experience with these but I always thought they consisted of a single dll so it would be easy to package them with the program.
I once, a long long time ago, built an application that stored user settings inside the registry. Don't know if that is still appreciated though.
What do you think is the best approach?
Code samples are very much appreciated!
I've taken both answers into account and built the following:
public static class IsolatedStorageExtensions
{
public static void SaveObject(this IsolatedStorage isoStorage, object obj, string fileName)
{
IsolatedStorageFileStream writeStream = new IsolatedStorageFileStream(fileName, FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(writeStream, obj);
writeStream.Flush();
writeStream.Close();
}
public static T LoadObject<T>(this IsolatedStorage isoStorage, string fileName)
{
IsolatedStorageFileStream readStream = new IsolatedStorageFileStream(fileName, FileMode.Open);
BinaryFormatter formatter = new BinaryFormatter();
T readData = (T)formatter.Deserialize(readStream);
readStream.Flush();
readStream.Close();
return readData;
}
}
A wrapper POCO object that contains that data to be serialized:
[Serializable]
internal class DataStoreContainer
{
public DataStoreContainer()
{
UserIDs = new List<int>();
}
public List<int> UserIDs { get; set; }
}
To consume these extensions:
private IsolatedStorageFile _isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);
private DataStoreContainer _data = new DataStoreContainer();
private const string FILENAME = "MyAppName.dat";
And in any method where you want to get the data :
_data = _isoStore.LoadObject<DataStoreContainer>(FILENAME);
To save the data:
_isoStore.SaveObject(_data, FILENAME);
Have you looked at Isolated Storage? It stores data in a local file, specific to that user (or to the application, depending on how you specify). You can easily serialize objects to and from the store because it's stream-based. It sounds like the perfect solution for your problem.
Since you state 10 items would be a lot I would vote for #1 or a variation of #1, Binary serialized... you don't seem to indicate that being able to read the data is important and binary data should give you smaller file sizes, though if 10 is a lot this still shouldn't be important.
That being said I enjoy what I've seen of db4objects.

Tool that auto-generate a code for accesing a xml-file

My application have a configuration xml-file. That file contains more than 50 program settings. At the present time I read and save each program setting separately. I guess It is not effiсiently for such tasks.
I need something that can auto-generate a code for load and save my program settings using predefined xml-schema.
I found a dataset in Add New Item dialog. Unfortunately, i cannot add new code to dataset1 such as events in set-accessors of properties because of this
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
Maybe, there is a tool that allows a user to generate a wrapper for accesing a xml-file ? Such as DataSet1, but with availability to add events.
Edit: I didn't mark a useful answer because i read an articles (link) which you give me. I will mark useful answer later.
If you are not willing to use app.config/web.config or the properties file (which Oded and Bruno recommend and I recommend as well), I highly recommend this utility:
Web Services Contract First (WSCF) Blue for VS2008 and VS2010
If you're on VS2005, you'll want this version of the tool: http://www.thinktecture.com/resourcearchive/tools-and-software/wscf (don't use the VS2008 version on this site. I could never get it to work right.)
Once you have the plugin installed into Visual Studio, you'll need an XSD schema of your XML file. (Google for an online XSD Generator.) Following the instructions found on the WSCF website, you can generate a wrapper class that will deserialize and reserialize your XML and give you an abstracted view of your XML.
I figure it is impossible (or at least very hard) to add new node/element TYPES, but adding new instances of existing node/element types, accessing to your data, editing the data, reordering nodes, and then saving back out are all easy.
Deserialization code looks like this:
private MyGeneratedXMLconfigClass config;
using (StreamReader sr = new StreamReader(filename))
{
XmlSerializer cXml = new XmlSerializer(typeof(MyGeneratedXMLconfigClass));
config = (MyGeneratedXMLconfigClass)cXml.Deserialize(sr);
}
Now your XML has been de-serialized into the "config" instance of your custom class. Then you can access the whole class as a series of nested values and Lists.
For example:
string errorFile = config.errorsFile;
List<string> actions = config.actionList;
var specialActions = from action in config.actionList
where action.contains("special")
select action;
Etc., etc. Then once you're done manipulating your data, you can re-serialize with this code:
using (StreamWriter wr = new StreamWriter(filename, false))
{
XmlSerializer cXml = new XmlSerializer(typeof(MyGeneratedXMLconfigClass));
cXml.Serialize(wr, config);
}
One of the very nice things about this tool is that it auto-generates all classes as "partial" classes, so that you can feel free to extend each class on your own without fear of your code getting stomped on in case you ever need to re-generate because the XSD/XML was changed.
I imagine this might sound like a lot, but the learning curve is actually pretty easy and once you get it installed and working, you'll realize how stupidly easy it is. It's worth it. I swear. :-)
If you have an appropriate xsd schema for your xml file microsoft provides xsd.exe, a small tool which auto-generates c# classes for this schema.
For details see: http://msdn.microsoft.com/en-us/library/x6c1kb0s%28VS.71%29.aspx
Why are you using hand rolled XML for configuration? What is wrong with the existing app.config and web.config schemas?
Why not use a .Settings file?
You can follow these steps:
1) generate an XSD file from your XML file. For There used to be a tool to infer schema from an XML file, I forgot what it's called. Currently I use my own utility, which basically runs this core routine to read an xml file and generate the corresponding xsd:
static void InferSchema(string fileName)
{
XmlWriter writer = null;
XmlSchemaInference infer = new XmlSchemaInference();
XmlSchemaSet sc = new XmlSchemaSet();
string outputXsd = fileName.Replace(".xml", ".xsd");
sc = infer.InferSchema(new XmlTextReader(fileName));
using (writer = XmlWriter.Create(new StreamWriter(outputXsd)))
{
foreach(XmlSchema schema in sc.Schemas())
{
schema.Write(writer);
Console.WriteLine(">> found schema - generated to {0}",
outputXsd);
}
}
}
2) run xsd.exe to generate a serializable class from the XSD file.
xsd.exe /c /n:MyNameSpaceHere MyGenerated.xsd
Next, you can read the XML file into the serializable class using XmlSerializer.Serialize() method. Something like this:
public static void Serialize<T>(T data, TextWriter writer)
{
try
{
XmlSerializer xs = new XmlSerializer(typeof(T));
xs.Serialize(writer, data);
}
catch (Exception e)
{
throw;
}
}
Finally, you can write back to the XML file from the class using the XmlSerializer.Deserialize() method, like this for instance:
public static void Deserialize<T>(out T data, XmlReader reader)
{
try
{
XmlSerializer xs = new XmlSerializer(typeof(T));
data = (T)xs.Deserialize(reader);
}
catch (Exception e)
{
reader.Close();
throw;
}
}
This is called a properties file. C# should have something similar to Java's Properties class where you can load all properties without hard-coding their names.
EDIT:
There's apparently no built-in properties parsing solution for C#. But you can easily implement your own. See here.
If you have an XSD file, you can generate classes from that. Besides the already mentioned xsd.exe from Microsoft (which hasn't been updated for quite some time), there are other tools for this. I am using XSD2Code, which allows generating strongly typed collections, lazy initialization, etc.
If you do not have an XSD, you can point the xsd.exe at your xml-file, and it will generate an XSD from that. The schema usually needs some work, but generally is a good starting point.
xsd.exe (instance).xml
You can use System.Xml.Serialization - it's very easy and you can serialize even class objects directly, like MyCustomClass (it even saves MyCustomClass public fields).
Deserializing the XML file will get a new instance of MyCustomClass, so such a feature is priceless.
Note one thing: you should add EVERY SINGLE TYPE you use in the class, but that's easy though.
I attached a complete project that does the thing you want. just change classes and objects and that will be all.
source code
for example (i'm shortening the code):
using System.Xml;
using System.Xml.Serialization;
using System.IO;
[XmlRootAttribute("Vendor")]
class Vendor{
[XmlAttribute]
Product prod;
}
[XmlRootAttribute("Product")]
class Product{
[XmlAttribute]
public string name="";
}
class Test{
Vendor v=new Vendor();
Product p=new Product();
p.name="a cake";
v.prod=p;
//add EVERY SINGLE TYPE you use in the serialized class.
Type[] type_list = { typeof(Product) };
XmlSerializer packer = new XmlSerializer(v.GetType(),type_list);
XmlWriter flusher = XmlWriter.Create(#"c:\bak.xml");
packer.Serialize(flusher, v);
flusher.Close();
XmlReader restorer = XmlReader.Create(#"c:\bak.xml");
Vendor v2 = (Vendor)packer.Deserialize(restorer);
//v2.prod.name is now "cake"
//COOL was my first impression :P
}

Categories