I am facing the problem regarding the following issue in wp7
"Type 'System.Windows.Media.Transform' cannot be serialized in C#"
When i call the below method to save my List data to isolated storage
SerializeHelper.SaveSetting("myfile.Xml",swaplist);
then then i am getting the exception.
public static class SerializeHelper
{
public static void SaveSetting<T>(string fileName, T dataToSave)
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
try
{
using (var stream = store.CreateFile(fileName))
{
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(stream, dataToSave);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return;
}
}
}
}
I am attaching the screenshot of structure of list data
How to resolve this?
Thank you for adding the screenshot... and pasting some code. Can't really see anything wrong.
does you VM only expose public primitive / serialisable types ? I have in past used something like this to serialise to iso store.
public static void SaveObjectToStorage<T>(T ObjectToSave)
{
TextWriter writer;
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream fs = isf.OpenFile(GetFileName<T>(), System.IO.FileMode.Create))
{
writer = new StreamWriter(fs);
XmlSerializer ser = new XmlSerializer(typeof(T));
ser.Serialize(writer, ObjectToSave);
writer.Close();
}
}
}
Related
I'm working within my PCL library and need to serialise a class and output to a file. I'm very short on space, so don't have the space for PCLStorage.
Currently I'm using this for the serialisation. IFilePath returns a file path from the non-PCL part.
IFilePath FilePath;
public void SerializeObject<T>(T serializableObject, string fileName)
{
if (serializableObject == null) { return; }
try
{
using (var ms = new MemoryStream())
{
var xmlDocument = new XDocument();
using (var writer = xmlDocument.CreateWriter())
{
var serialize = new DataContractSerializer(typeof(T));
serialize.WriteObject(writer, serializableObject);
xmlDocument.Save(ms, SaveOptions.None);
}
}
}
catch (Exception ex)
{
//Log exception here
}
}
When I try to save, nothing is showing. I have a feeling it's because I'm not outputting the stream to a file, but I'm at a loss as how to do this.
You are trying to save to a file, an action which is specific for each platform.
PCLStorage is implementing this functionality for each platform and this is what you will have to do also if you can"t use it.
In you case what you have to do is to create the stream (in each platform) in your non pcl code and then pass it to your function which will look like this:
public void SerializeObject<T>(T serializableObject, Stream fileStream)
{
if (serializableObject == null) { return; }
try
{
var xmlDocument = new XDocument();
using (var writer = xmlDocument.CreateWriter())
{
var serialize = new DataContractSerializer(typeof(T));
serialize.WriteObject(writer, serializableObject);
xmlDocument.Save(fileStream, SaveOptions.None);
}
}
catch (Exception ex)
{
//Log exception here
}
}
more on pcl here.
Problem is that your variable ms in using (var ms = new MemoryStream()) is empty and does not point to any file location of which MemoryStream does not receive a filepath as argument. I propose you use a StreamWriter instead and pass the your FileStream to it. Example
Use your fileName to create a FileStream which inherits from the Stream class then replace the Memory stream with the newly created filestream like this.
using(FileStream stream = File.OpenWrite(fileName))
{
var xmlDocument = new XDocument();
using (var writer = xmlDocument.CreateWriter())
{
var serialize = new DataContractSerializer(typeof(T));
serialize.WriteObject(writer, serializableObject);
xmlDocument.Save(stream, SaveOptions.None);
}
}
Hope this helps.
This is a follow-up question from How to create an empty xml in Windows Phone 8.
I did this to create the xml:
public void create()
{
List<DataModel> __dataList = new List<DataModel>();
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile("Data.xml", FileMode.Create))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<DataModel>));
using (XmlWriter xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
{
serializer.Serialize(stream, __dataList);
}
}
}
}
When I try to read it with this code, I get another System.InvalidOperationException
public void read()
{
List<DataModel> __dataList = new List<DataModel>();
try
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile("Data.xml", FileMode.Open))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<DataModel>));
__dataList = (List<DataModel>)serializer.Deserialize(stream);
}
}
}
catch (Exception e)
{
string s = e.Message;
e.ToString();
}
}
The exception message is "There is an error in XML document (2, 118)." What is wrong with my code?
Edit: Inner exception is "Data at the root level is invalid. Line 2, position 118."
Edit 2: I read the contents of the xml using StreamReader.ReadToEnd() before deserializing and this is the return string:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfDataModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
This is my first time working with xml, so the issue may be a simple one but I may not realise it. Any help?
Does the code below also give an error? And what is the construction of DataModel?
public void create()
{
List<DataModel> __dataList = new List<DataModel>();
//XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
//xmlWriterSettings.Indent = true;
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile("Data.xml", FileMode.Create))
{
try
{
XmlSerializer serializer = new XmlSerializer(typeof(List<DataModel>));
//using (XmlWriter xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
//{
serializer.Serialize(stream, __dataList);
//}
}
catch { }
}
}
}
public void read()
{
List<DataModel> __dataList = new List<DataModel>();
try
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile("Data.xml", FileMode.Open))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<DataModel>));
__dataList = (List<DataModel>)serializer.Deserialize(stream);
}
}
}
catch (Exception e)
{
string s = e.Message;
e.ToString();
}
}
And somewhere:
public class DataModel
{ }
That code above works for me.
I'm attempting to write some data from an object to an XML document and am following a tutorial online, however I have run into a problem which I can't seem to fathom, the code I'm using to initiate the creation of the document isusing (XmlWriter writer = XmlWriter.Create("myData.xml")) and I'm getting an error with the "myData.xml", the errors I get are:
The best overload method match for 'System.Xml.XmlWriter.Create(System.Xml.XmlWriter)'
has some invalid arguments
Argument 1: cannot convert from 'string' to 'System.Xml.XmlWriter'
Is XmlWriter compatible with Windows Phone? And if not will I have to change huge amounts of code that writes to the file?
Edit: Here's my code
string output = SerializeToString<AppData>(rulesData);
using (XmlWriter writer = XmlWriter.Create(output))
{
writer.WriteStartDocument();
writer.WriteStartElement("myData");
writer.WriteElementString("Starting Cash", rulesData.myStartingCash);
writer.WriteElementString("Land on Go Data", rulesData.myLandOnGo);
writer.WriteElementString("Free Parking Data", rulesData.myFreeParking);
writer.WriteElementString("Full Circuit Data", rulesData.myFullCircuit);
writer.WriteElementString("Auction Data", rulesData.myAuction);
writer.Flush();
writer.WriteEndElement();
writer.WriteEndDocument();
}
Thanks! -Ryan
You can use this code:
public static void SerializeToStream<T>(Stream stream, object model)
{
var writer = XmlWriter.Create(stream);
var s = new XmlSerializer(typeof(T));
s.Serialize(writer, model);
}
public static string SerializeToString<T>(object model)
{
var xmlSer = new XmlSerializer(typeof(T));
using (var stream = new MemoryStream())
{
SerializeToStream<T>(stream, model);
var s = stream.ToArray();
return System.Text.Encoding.UTF8.GetString(s, 0, s.Length);
}
}
public static void SerializeToFile<T>(string filename, object model)
{
using (FileStream stream = File.Open(filename, FileMode.Create))
{
SerializeToStream<T>(stream, model);
}
}
Your code doesn't compile because you pass a string instead of a stream to XmlWriter
Usage:
string output = SerializeToString<ClassName>(instanceOfClass);
I am using this code as my IsolatedStorage Helper.
public class IsolatedStorageHelper
{
public const string MyObjectFile = "History.xml";
public static void WriteToXml<T>(T data, string path)
{
// Write to the Isolated Storage
var xmlWriterSettings = new XmlWriterSettings { Indent = true };
try
{
using (var myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var stream = myIsolatedStorage.OpenFile(path, FileMode.Create))
{
var serializer = new XmlSerializer(typeof(T));
using (var xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
{
serializer.Serialize(xmlWriter, data); //This line generates the exception
}
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
//Dispatcher.BeginInvoke(() => MessageBox.Show(ex.StackTrace));
//MessageBox.Show(ex.StackTrace);
}
}
public static T ReadFromXml<T>(string path)
{
T data = default(T);
try
{
using (var myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var stream = myIsolatedStorage.OpenFile(path, FileMode.CreateNew))
{
var serializer = new XmlSerializer(typeof(T));
data = (T)serializer.Deserialize(stream);
}
}
}
catch
{
return default(T);
//add some code here
}
return data;
}
}
I am saving an object of my class PdfFile, which has ImageSource as one of its properties.
But an exception is generated while saving the object and it states System.InvalidOperationException: The type System.Windows.Media.Imaging.BitmapImage was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
I would like to know what this means, and how I would solve this.
Thank you
You're trying to serialize a class that contains a variable / property of type BitmapImage. You can't serialize that type, so you get the mentioned exception. Try to work around by serializing a name or something like this and instantiating the BitmapImage on deserialization from that information.
If you want to save something in iso storage which is not serializable then you can still do so if you write your own serialize method.
Presumably the BitmapImage is not an original part of your app or you would already have the file for it, so I guess it must be a newly acquired bitmap.
Convert your BitmapImage to an array of bytes and you should have no problem.
I have a GetServiceMap() method which calls deserializer who then opens the stream and reads something from it.
The problem is that i have a GetAllGroups() method also who calls deserializer over the same stream.
How would i syncronize it? With ManualResetEvent maybe?
public ServiceMapModel GetServiceMap()
{
s._mre.WaitOne();
return s.Deserialize();
}
public List<Group> GetAllGroups()
{
s._mre.WaitOne();
return s.Deserialize().Groups;
}
Deserialize method:
public ManualResetEvent _mre = new ManualResetEvent(true);
public ServiceMapModel Deserialize()
{
_serviceMap = new ServiceMapModel();
_mre.Reset();
try
{
using (var fileStream = new FileStream(Settings.Path, FileMode.Open))
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;
using (XmlReader reader = XmlReader.Create(fileStream, settings))
{
_serviceMap = _serializer.Deserialize(reader) as ServiceMapModel;
}
fileStream.Close();
}
}
catch (IOException)
{
}
_mre.Set();
return _serviceMap;
}
For your case basic lock should be enough - no reason to use more complicated objects.
I would actually cache result of deserialization instead of reading from file every time, but it is your call.