Write/Restore ObservableCollection<T> - c#

I have huge problem with saveing and restore ObservableCollection to IsolatedData.
I'm trying with this code.
Helper class for Observable
public class ListItem {
public String Title { get; set; }
public bool Checked { get; set; }
public ListItem(String title, bool isChecked=false) {
Title = title;
Checked = isChecked;
}
private ListItem() { }
}
IsoHelper
public class IsoStoreHelper {
private static IsolatedStorageFile _isoStore;
public static IsolatedStorageFile IsoStore {
get { return _isoStore ?? (_isoStore = IsolatedStorageFile.GetUserStoreForApplication()); }
}
public static void SaveList<T>(string folderName, string dataName, ObservableCollection<T> dataList) where T : class {
if (!IsoStore.DirectoryExists(folderName)) {
IsoStore.CreateDirectory(folderName);
}
if (IsoStore.FileExists(folderName + "\\" + dataName+".dat")) {
IsoStore.DeleteFile(folderName + "\\" + dataName + ".dat");
}
string fileStreamName = string.Format("{0}\\{1}.dat", folderName, dataName);
try {
using (var stream = new IsolatedStorageFileStream(fileStreamName, FileMode.Create, IsoStore)) {
var dcs = new DataContractSerializer(typeof(ObservableCollection<T>));
dcs.WriteObject(stream, dataList);
}
} catch (Exception e) {
Debug.WriteLine(e.Message);
}
}
public static ObservableCollection<T> LoadList<T>(string folderName, string dataName) where T : class {
var retval = new ObservableCollection<T>();
if (!IsoStore.DirectoryExists(folderName) || !IsoStore.FileExists(folderName + "\\" + dataName + ".dat")) {
return retval;
}
string fileStreamName = string.Format("{0}\\{1}.dat", folderName, dataName);
var isf = IsoStore;
try {
var fileStream = IsoStore.OpenFile(fileStreamName, FileMode.OpenOrCreate);
if (fileStream.Length > 0) {
var dcs = new DataContractSerializer(typeof(ObservableCollection<T>));
retval = dcs.ReadObject(fileStream) as ObservableCollection<T>;
}
} catch {
retval = new ObservableCollection<T>();
}
return retval;
}
}
And I'm trying to use it this way
public partial class MainPage : PhoneApplicationPage{
public ObservableCollection<ListItem> ListItems = new ObservableCollection<ListItem>();
bool isListSaved;
private void Panorama_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) {
if (strTag.Equals("list") ) {
isListSave = false;
ListItems = IsoStoreHelper.LoadList<ListItem>("settings", "ListItems");
} else if (!isListSave) {
IsoStoreHelper.SaveList<ListItem>("settings", "ListItems", ListItems);
}
}
}
I keep getting A first chance exception of type 'System.Security.SecurityException' occurred in System.Runtime.Serialization.ni.dll when I try read saved file at line ReadObject(fileStream) but the FileAccess looks fine.
Any conclusion will be appreciated.
SOLVED:
Like Dmytro Tsiniavskyi said I totaly forgot about [DataContract] and [DataMember] in ListItem. Whats more I found better solution for saving and loading data. I end up with this code for ListItem
[DataContract]
public class ListItem {
[DataMember]
public String Title { get; set; }
[DataMember]
public bool Checked { get; set; }
public ListItem(String title, bool isChecked=false) {
Title = title;
Checked = isChecked;
}
private ListItem() { }
}
And this code for save/load collection which was originally founded here and modified a litte bit for better useage.
public partial class IsolatedRW {
public static void SaveData<T>(string fileName, T dataToSave) {
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
try {
if (store.FileExists(fileName)) {
store.DeleteFile(fileName);
}
if (!store.DirectoryExists("Settings")) store.CreateDirectory("Settings");
IsolatedStorageFileStream stream;
using (stream = store.OpenFile("Settings/"+fileName+".xml", System.IO.FileMode.Create, System.IO.FileAccess.Write)) {
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(stream, dataToSave);
}
stream.Close();
} catch (System.Security.SecurityException e) {
//MessageBox.Show(e.Message);
return;
}
Debug.WriteLine(store.FileExists("Settings/" + fileName + ".xml"));
}
}
public static T ReadData<T>(string fileName) {
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
Debug.WriteLine(store.FileExists("Settings/" + fileName + ".xml"));
if (store.FileExists("Settings/" + fileName + ".xml")) {
IsolatedStorageFileStream stream;
using (stream = store.OpenFile("Settings/"+fileName+".xml", FileMode.OpenOrCreate, FileAccess.Read)) {
try {
var serializer = new DataContractSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
} catch (Exception) {
return default(T);
}
}
stream.Close();
}
return default(T);
}
}
}

Try to add [DataContract] attribute for your ListItem class.
[DataContract]
public class ListItem {
[DataMember]
public String Title { get; set; }
[DataMember]
public bool Checked { get; set; }
public ListItem(String title, bool isChecked=false) {
Title = title;
Checked = isChecked;
}
private ListItem() { }
}

Related

C# Can i implement interface with IEnumerable object and struct?

So I want to write an interface, which should be able to be implemented with any data. This is interface i wrote till now. The reason I chose IEnumerable is because I need to give class Computer or struct Processor
public interface IData<T> where T : IEnumerable<object>
{
public T ReadData();
public void WriteData(T list);
}
And I have two different datas, one is Computer, which is a class. And the other one is Processor (struct)
public struct Processor
{
public string Name { get; set; }
public string AmazonLink { get; set; }
public string AmazonBin { get; set; }
public Processor(string name, string link)
{
Name = name;
try
{
//constructor parses elements which is needed to generate AmazonURL in URLGenerator project
AmazonLink = link.Substring(0, link.IndexOf("&dc"));
string binStart = link.Substring(link.IndexOf("bin%") + 4);
AmazonBin = "%7C" + binStart.Substring(2);
}
catch (Exception e)
{
throw new InnerCustomException("Erorr occured while trying to substring the link", e);
}
}
I tried to do that like this, but it seems like I am not allowed to do that because of boxing?
public class ProcessorServiceCSV : IData<IEnumerable<Processor>>
{ private string Path { get; set; }
private FileMode Filemode { get; set; }
public ProcessorServiceCSV(string path, FileMode fileMode)
{
Path = path;
Filemode = fileMode;
}
//reads Processor list from CSV file
public IEnumerable<Processor> ReadData()
{
try
{
using (var reader = new StreamReader(Path))
using (var csv = new CsvReader(reader))
{
csv.Configuration.CultureInfo = CultureInfo.InvariantCulture;
csv.Configuration.Delimiter = ",";
csv.Configuration.RegisterClassMap<ProcessorMap>();
var records = csv.GetRecords<Processor>().ToList();
return records.ToList();
}
}
catch (FileNotFoundException)
{
throw new DataCustomException("File not found", this);
}
catch (Exception e)
{
throw new DataCustomException("Something's wrong happened:" + e.Message, this);
}
} public void WriteData(IEnumerable<Processor> processors)
{
try
{
using (var stream = File.Open(Path, Filemode))
using (StreamWriter sw = new StreamWriter(stream))
using (CsvWriter cw = new CsvWriter(sw))
{
foreach (Processor processor in processors)
{
cw.Configuration.RegisterClassMap<ProcessorMap>();
cw.WriteRecord<Processor>(processor);
cw.NextRecord();
}
}
}
catch (FileNotFoundException)
{
throw new DataCustomException("File not found", this);
}
catch (FileLoadException)
{
throw new DataCustomException("File could not be opened", this);
}
catch (Exception e)
{
throw new DataCustomException("Something's wrong happened:" + e.Message, this);
}
}
}
}
I know I could change Processor from struct to class, but is it possible to keep struct? Thank you in advance
You have a lot of other problems, including not giving us a complete, working bit of code.
However, it looks like you should be able to do what you want to do if you use an Interface for the Processor struct instead of the actual struct type.
Also, notice how I changed the type for T in your classes. You don't need IEnumerable in your T constraint. I did delete some of your code to get it to somewhat work (the exception in the struct constructor, e.g.), so you will need to do some more work here.
public interface IData<T>
{
IEnumerable<T> ReadData();
void WriteData(IEnumerable<T> list);
}
public interface IProcessor {
string Name { get; set; }
string AmazonLink { get; set; }
string AmazonBin { get; set; }
}
public struct Processor : IProcessor
{
public string Name { get; set; }
public string AmazonLink { get; set; }
public string AmazonBin { get; set; }
public Processor(string name, string link)
{
Name = name;
//constructor parses elements which is needed to generate AmazonURL in URLGenerator project
AmazonLink = link.Substring(0, link.IndexOf("&dc"));
string binStart = link.Substring(link.IndexOf("bin%") + 4);
AmazonBin = "%7C" + binStart.Substring(2);
}
}
public class ProcessorServiceCSV<T> : IData<T> where T: IProcessor
{ private string Path { get; set; }
private FileMode Filemode { get; set; }
public ProcessorServiceCSV(string path, FileMode fileMode)
{
Path = path;
Filemode = fileMode;
}
//reads Processor list from CSV file
public IEnumerable<T> ReadData()
{
try
{
using (var reader = new StreamReader(Path))
using (var csv = new CsvReader(reader))
{
csv.Configuration.CultureInfo = CultureInfo.InvariantCulture;
csv.Configuration.Delimiter = ",";
csv.Configuration.RegisterClassMap<ProcessorMap>();
var records = csv.GetRecords<Processor>().ToList();
return records.ToList();
}
}
catch (FileNotFoundException)
{
throw new DataCustomException("File not found", this);
}
catch (Exception e)
{
throw new DataCustomException("Something's wrong happened:" + e.Message, this);
}
}
}
Is this the basic skeleton code of what you are trying to do? Note that the generic collection is IEnumerable<T> and not IEnumetable<object> and hence I updated your IData<T> definition
public class Computer
{
}
public struct Processor
{
}
public interface IData<T>
{
IEnumerable<T> ReadData();
void WriteData(IEnumerable<T> list);
}
public class ComputerData : IData<Computer>
{
public IEnumerable<Computer> ReadData()
{
throw new NotImplementedException();
}
public void WriteData(IEnumerable<Computer> list)
{
throw new NotImplementedException();
}
}
public class ProcessorData : IData<Processor>
{
public IEnumerable<Processor> ReadData()
{
throw new NotImplementedException();
}
public void WriteData(IEnumerable<Processor> list)
{
throw new NotImplementedException();
}
}
Please indicate if this code meets your requirements, and if not why.

Download Bundle File into a folder inside another folder

I made an application to download files into a folder inside another folder.
The name for the folder obtained from DataFile name from database and match the name of the image that has been downloaded.
I'm having a problem, that when downloading to a folder for the first bundle of data is fine, but at the time of downloading the data bundle again the previous folder and the new folder also download both files.
When downloading the files that differ it will create a new folder again and the two previous folders are also downloaded the file. For more details, can see in the image below:
And should one folder contains two files.
JSON:
RHData Class:
[PrimaryKey]
public string SKU { get; set; }
public string Judul { get; set; }
public string Tipe { get; set; }
public string Harga { get; set; }
public string Gratis { get; set; }
public string DataFile { get; set; }
RHViewModel class:
class RHViewModel
{
private string sku = string.Empty;
public string SKU
{
get { return sku; }
set
{
if (sku == value)
return;
sku = value;
RaisePropertyChanged("SKU");
}
}
private string judul = string.Empty;
public string Judul
{
get { return judul; }
set
{
if (judul == value)
return;
judul = value;
RaisePropertyChanged("Judul");
}
}
private string tipe = string.Empty;
public string Tipe
{
get { return tipe; }
set
{
if (tipe == value)
return;
tipe = value;
RaisePropertyChanged("Tipe");
}
}
private string harga = string.Empty;
public string Harga
{
get { return harga; }
set
{
if (harga == value)
return;
harga = value;
RaisePropertyChanged("Harga");
}
}
private string cover = string.Empty;
private string gratis = string.Empty;
public string Gratis
{
get { return gratis; }
set
{
if (gratis == value)
return;
gratis = value;
RaisePropertyChanged("Gratis");
}
}
private string dataFile = string.Empty;
public string DataFile
{
get { return dataFile; }
set
{
if (dataFile == value)
return;
dataFile = value;
RaisePropertyChanged("DataFile");
}
}
public RHViewModel GetItem(string itemSku)
{
var item = new RHViewModel();
using (var db = new SQLiteConnection(App.SQLITE_PLATFORM, App.DB_PATH))
{
var _item = (db.Table<RHData>().Where(
c => c.SKU == itemSku)).Single();
item.SKU = _item.SKU;
item.Judul = _item.Judul;
item.Tipe = _item.Tipe;
item.Harga = _item.Harga;
item.Gratis = _item.Gratis;
item.DataFile = _item.DataFile;
}
return item;
}
public string SaveItem(RHViewModel item)
{
string result = string.Empty;
using (var db = new SQLiteConnection(App.SQLITE_PLATFORM, App.DB_PATH))
{
try
{
var existingItem = (db.Table<RHData>().Where(
c => c.SKU == item.sku)).SingleOrDefault();
if (existingItem != null)
{
existingItem.SKU = item.SKU;
existingItem.Judul = item.Judul;
existingItem.Tipe = item.Tipe;
existingItem.Harga = item.Harga;
existingItem.Gratis = item.Gratis;
existingItem.DataFile = item.DataFile;
int success = db.Update(existingItem);
}
else
{
int success = db.Insert(new RHData()
{
SKU = item.SKU,
Judul = item.Judul,
//Deskripsi = item.Deskripsi,
Tipe = item.Tipe,
Harga = item.Harga,
Gratis = item.Gratis,
//Cover = item.Cover,
//File = item.File,
DataFile = item.DataFile
});
}
result = "Success";
}
catch
{
result = "This item was not saved.";
}
}
return result;
}
public string DeleteItem(string itemDataFile)
{
string result = string.Empty;
using (var dbConn = new SQLiteConnection(App.SQLITE_PLATFORM, App.DB_PATH))
{
var existingItem = dbConn.Query<RHData>("select * from RH where DataFile =" + itemDataFile).FirstOrDefault();
if (existingItem != null)
{
dbConn.RunInTransaction(() =>
{
dbConn.Delete(existingItem);
if (dbConn.Delete(existingItem) > 0)
{
result = "Success";
}
else
{
result = "This item was not removed";
}
});
}
return result;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
RHItemsViewModel Class:
class RHItemsViewModel : RHViewModel
{
private ObservableCollection<RHViewModel> items;
public ObservableCollection<RHViewModel> Items
{
get
{
return items;
}
set
{
items = value;
RaisePropertyChanged("Items");
}
}
public ObservableCollection<RHViewModel> GetItems()
{
items = new ObservableCollection<RHViewModel>();
using (var db = new SQLiteConnection(App.SQLITE_PLATFORM, App.DB_PATH))
{
var query = db.Table<RHData>().OrderBy(c => c.SKU);
foreach (var _item in query)
{
var item = new RHViewModel()
{
//SKU = _item.SKU,
SKU = _item.SKU,
Judul = _item.Judul,
//Deskripsi = _item.Deskripsi,
Tipe = _item.Tipe,
Harga = _item.Harga,
Gratis = _item.Gratis,
//Cover = _item.Cover,
//File = _item.File,
DataFile = _item.DataFile
};
items.Add(item);
}
}
return items;
}
}
}
App.Xaml.CS
public static string DB_PATH = Path.Combine(ApplicationData.Current.LocalFolder.Path, "RH.sqlite");
public static SQLite.Net.Platform.WinRT.SQLitePlatformWinRT SQLITE_PLATFORM;
public App()
{
Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(
Microsoft.ApplicationInsights.WindowsCollectors.Metadata |
Microsoft.ApplicationInsights.WindowsCollectors.Session);
this.InitializeComponent();
this.Suspending += OnSuspending;
SQLITE_PLATFORM = new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT();
if (!CheckFileExists("RH.sqlite").Result)
{
using (var db = new SQLiteConnection(SQLITE_PLATFORM, DB_PATH))
{
db.CreateTable<RHData>();
}
}
}
private async Task<bool> CheckFileExists(string fileName)
{
try
{
var store = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
return true;
}
catch
{
}
return false;
}
Code:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//GC.Collect();
BukuAudio dlList = e.Parameter as BukuAudio;
if (dlList != null)
{
Queue<DownloadOperation> downloadOperationList = new Queue<DownloadOperation>();
BackgroundDownloader downloader = new BackgroundDownloader();
DownloadProgress.Visibility = Visibility.Visible;
downloadfilename.Visibility = Visibility.Visible;
statusdownload.Visibility = Visibility.Visible;
deleteBtn.Visibility = Visibility.Collapsed;
viewBtn.Visibility = Visibility.Collapsed;
foreach (var path in dlList.BundlePath)
{
DownloadBuku(path);
for (int i = 0; i<dlList.BundlePath.Count;i++)
{
downloadfilename.Text = dlList.BundleName.ElementAt(i);
Uri uri = new Uri(path);
string filename = path.Substring(uri.LocalPath.LastIndexOf("/") + 1);
downloadfilename.Text = String.Format("Unduh '{0}'", filename);
}
}
DownloadGambar(dlList.Cover);
}
else
{
DownloadProgress.Visibility = Visibility.Collapsed;
downloadfilename.Visibility = Visibility.Collapsed;
statusdownload.Visibility = Visibility.Collapsed;
deleteBtn.Visibility = Visibility.Visible;
viewBtn.Visibility = Visibility.Visible;
}
bookAudio = e.Parameter as BookAudio;
}
private async void downloadClicked(object sender, RoutedEventArgs e)
{
Uri uri = new Uri(itemDetail.BundlePath.First());
string filename = System.IO.Path.GetFileName(uri.LocalPath);
string statustext = String.Format("Download Buku '{0}'?", itemDetail.Judul);
string sudahada = String.Format("Buku '{0}' sudah ada/sedang didownload", itemDetail.Judul);
MessageDialog messageDialog;
try
{
StorageFolder library = await ApplicationData.Current.LocalFolder.CreateFolderAsync("library", CreationCollisionOption.OpenIfExists);
var file = await library.GetFileAsync(filename);
messageDialog = new MessageDialog(sudahada, "Buku sudah ada");
messageDialog.Commands.Add(new UICommand("Library", (command) =>
{
this.Frame.Navigate(typeof(library.LibraryPage));
}));
messageDialog.Commands.Add(new UICommand("Batal", (command) =>
{
//rootPage.NotifyUser("The 'Don't install' command has been selected.", NotifyType.StatusMessage);
}));
}
catch (FileNotFoundException ex)
{
//file not exists show download dialog
// Create the message dialog and set its content and title
messageDialog = new MessageDialog(statustext, "Download");
// Add commands and set their callbacks
messageDialog.Commands.Add(new UICommand("Download", (command) =>
{
itemsViewModel = new RHItemsViewModel();
itemsViewModel.SaveItem(new RHViewModel()
{
SKU = itemDetail.SKU.ToString(),
Judul = itemDetail.Judul.ToString(),
Tipe = itemDetail.Tipe.ToString(),
Harga = itemDetail.Harga.ToString(),
Gratis = itemDetail.Gratis.ToString(),
DataFile = itemDetail.DataFile.ToString()
});
this.Frame.Navigate(typeof(library.LibraryPage), itemDetail);
}));
messageDialog.Commands.Add(new UICommand("Batal", (command) =>
{
//rootPage.NotifyUser("The 'Don't install' command has been selected.", NotifyType.StatusMessage);
}));
}
// Show the message dialog
await messageDialog.ShowAsync();
}
}
Library Page:
private async void DownloadBuku(string fileLocation)
{
itemsViewModel = new RHItemsViewModel();
items = new ObservableCollection<RHViewModel>();
using (var dbConn = new SQLiteConnection(App.SQLITE_PLATFORM, App.DB_PATH))
{
var existingItem = dbConn.Table<RHData>().OrderBy(c => c.DataFile);
if (existingItem != null)
{
foreach (var _item in existingItem)
{
var item = new RHViewModel()
{
DataFile = _item.DataFile
};
items.Add(item);
var uri = new Uri(fileLocation);
var downloader = new BackgroundDownloader();
StorageFolder library = await installedLocation.CreateFolderAsync("library", CreationCollisionOption.OpenIfExists);
StorageFolder pdf = await library.CreateFolderAsync(item.DataFile.ToString(), CreationCollisionOption.OpenIfExists);
string filename = System.IO.Path.GetFileName(uri.LocalPath);
StorageFile file = await pdf.CreateFileAsync(filename,
CreationCollisionOption.ReplaceExisting);
DownloadOperation download = downloader.CreateDownload(uri, file);
await StartDownloadAsync(download);
}
}
}
}
BukuAudio Class:
class BukuAudio
{
public string SKU { get; set; }
public string Judul { get; set; }
public string Deskripsi { get; set; }
public string Tipe { get; set; }
public string NamaTipe { get; set; }
public string Harga { get; set; }
public string Cover { get; set; }
public string File { get; set; }
public string Gratis { get; set; }
public string Tanggal { get; set; }
public string DataFile { get; set; }
public JsonArray Bundle_file { get; set; }
public List<string> BundleName { get; set; }
public List<string> BundlePath { get; set; }
}
How to handle it?
Note:
First Bundle File downloaded in the folder "bundle.24b"
Second Bundle file downloaded files in the folder "bundle.23b"
Third Bundle downloaded file in the folder "bundle.22b
Supposedly the file name "bundle.24b ....." downloaded in folder bundle.24b, the file name "bundle.23b ....." downloaded in folder bundle.23b, the file name "bundle.22b ....." downloaded in folder bundle.22b

Avoid duplicated code in XML serializable classes

I have two Serializable classes with very similar code. Actually, except for the part where specific constructor is called, serialization code is identical.
Is there a way to create a common class to contain the common parts, so that specific classes (subclasses?) can implement only the constructor part? I can think of generics, factory pattern, but could not figure out how to do it.
// Fictitious classes
[Serializable]
public class FlightParameters {
public double MaxHeight { get; set; }
pulbic double MaxSpeedKmPerHour { get; set; }
public static FlightParameters Load(String fname) {
FlightParameters result;
using (var fs = new FileStream(fname, FileMode.OpenOrCreate)) {
var serializer = new XmlSerializer(typeof(FlightParameters));
try {
result = (FlightParameters)serializer.Deserialize(fs);
}
// catch "file not found"
catch (InvalidOperationException) {
result = new FlightParameters() {
MaxHeight = 30000;
MaxSpeedKmPerHour = 1500;
}
serializer.Serialize(fs, result);
}
return result;
}
}
}
[Serializable]
public class SailingParameters {
public double MaxDepth { get; set; }
pulbic double MaxSpeedKnots { get; set; }
public static SailingParameters Load(String fname) {
SailingParameters result;
using (var fs = new FileStream(fname, FileMode.OpenOrCreate)) {
var serializer = new XmlSerializer(typeof(SailingParameters));
try {
result = (SailingParameters)serializer.Deserialize(fs);
}
// catch "file not found"
catch (InvalidOperationException) {
result = new SailingParameters() {
MaxDepth = 13000;
MaxSpeedKnots = 15;
}
serializer.Serialize(fs, result);
}
return result;
}
}
}
Usage:
FlightParameters _fparam = FlightParameters.Load(somePath);
SailingParameters _sparam = SailingParameters.Load(someOtherPath);
The easiest way I can see to do that would be something like:
static class XmlUtils {
public static T Load<T>(string filename, Func<T> onMissing = null)
where T : class, new()
{
using (var fs = File.OpenRead(filename)) {
var serializer = new XmlSerializer(typeof(T));
try {
return (T)serializer.Deserialize(fs);
} catch (InvalidOperationException) { // catch "file not found"
return onMissing == null ? new T() : onMissing();
}
}
}
}
allowing something like;
public static SailingParameters Load(string filename) {
return XmlUtils.Load<SailingParameters>(filename, () => new SailingParameters {
MaxDepth = 13000;
MaxSpeedKnots = 15;
});
}

Remove namespace from DataContract doesn't work

I have to two simple serialize/desirialize methods,
Mapping:
[System.Runtime.Serialization.DataContract(Namespace = "", Name = "PARAMS")]
public sealed class CourseListRequest {
[DataMember(Name = "STUDENTID")]
public int StudentId { get; set; }
[DataMember(Name = "YEAR")]
public string Year { get; set; }
[DataMember(Name = "REQUESTTYPE")]
public int RequestType { get; set; }
}
public static string Serialize<T>(this T value) {
if (value == null) throw new ArgumentNullException("value");
try {
var dcs = new DataContractSerializer(typeof (T));
string xml;
using (var ms = new MemoryStream()) {
dcs.WriteObject(ms, value);
xml = Encoding.UTF8.GetString(ms.ToArray());
}
return xml;
}
catch (Exception e) {
throw;
}
}
public static T Deserialize<T>(this string xml) where T : class {
if (string.IsNullOrEmpty(xml)) {
return default(T);
}
try {
var dcs = new DataContractSerializer(typeof (T));
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml))) {
ms.Position = 0;
return dcs.ReadObject(ms) as T;
}
}
catch (Exception e) {
throw;
}
}
result:
<PARAMS xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><REQUESTTYPE>36</REQUESTTYPE><STUDENTID>0</STUDENTID><YEAR>תשע</YEAR></PARAMS>
How to remove xmlns:i="http://www.w3.org/2001/XMLSchema-instance" ?? On serializing
Switch to using XmlSerializer
System.Xml.Serialization.XmlSerializer
This will generate plain XML with no namespaces

How to save/load an ObservableCollection of custom class type in WP7

I have created a custom class, named BrowserItem that I am using in my application, that contains a lot of values. I am using this class in an ObservableCollection to store a collection of items. For some reason, although this implementation works while my application is running, I cannot properly get these values to persist when the application closes and then reopens. I am not sure how to properly save and then reload the ObservableCollection of type BrowserItem.
BrowserItem.cs
[DataContract]
public class BrowserItem
{
[DataMember]
public FullWebBrowser Browser
{
get;
set;
}
[DataMember]
public string Url
{
get;
set;
}
[DataMember]
public BitmapImage ImageUri
{
get;
set;
}
[DataMember]
public string Title
{
get;
set;
}
[DataMember]
public string Notification
{
get;
set;
}
[DataMember]
public bool DisplayNotification
{
get
{
return !string.IsNullOrEmpty(this.Notification);
}
}
[DataMember]
public string Message
{
get;
set;
}
[DataMember]
public string GroupTag
{
get;
set;
}
[DataMember]
//for translation purposes (bound to HubTile Title on MainPage)
public string TileName
{
get;
set;
}
}
Setting.cs (my class that saves and loads from IsolatedStorage)
public class Setting<T>
{
string name;
T value;
T defaultValue;
bool hasValue;
public Setting(string name, T defaultValue)
{
this.name = name;
this.defaultValue = defaultValue;
}
public T Value
{
get
{
//Check for the cached value
if (!this.hasValue)
{
//Try to get the value from Isolated Storage
if (!IsolatedStorageSettings.ApplicationSettings.TryGetValue(this.name, out this.value))
{
//It hasn't been set yet
this.value = this.defaultValue;
IsolatedStorageSettings.ApplicationSettings[this.name] = this.value;
}
this.hasValue = true;
}
return this.value;
}
set
{
//Save the value to Isolated Storage
IsolatedStorageSettings.ApplicationSettings[this.name] = value;
this.value = value;
this.hasValue = true;
}
}
public T DefaultValue
{
get { return this.defaultValue; }
}
// Clear cached value
public void ForceRefresh()
{
this.hasValue = false;
}
}
Settings.cs (where the ObservableCollection is initialized)
public static Setting<ObservableCollection<BrowserItem>> BrowserList = new Setting<ObservableCollection<BrowserItem>>("Browsers", new ObservableCollection<BrowserItem>());
public static Setting<string> InitialUri = new Setting<string>("InitialUri", "http://www.bing.com");
In the above class, InitialUri works fine when new values are saved and then used later, but I believe the issue with the ObservableCollection is its type being BrowserItem. I do not know how to make it so BrowserItem will be able to be used in the ObservableCollection to save and retrieve items that are added to the ObservableCollection. An example of adding an item is below
TabsPage.xaml.cs
void addNew_Click(object sender, EventArgs e)
{
BitmapImage newTileImage = new BitmapImage();
var newItem = new BrowserItem() { Browser = new FullWebBrowser(), Url = "http://www.bing.com", ImageUri = newTileImage, Title = "new", /*Notification = "",*/ Message = "new browser", GroupTag = "TileGroup", TileName = "new" };
newItem.Browser.InitialUri = Settings.InitialUri.Value;
Settings.BrowserList.Value.Add(newItem);
}
Items in the ObservableCollection can be used while the application is active, but not once the application is activated once closed?
I had same kind of requirement in my earlier project
Create a class to save and read data from the ObservableCollection
public class SerializeHelper
{
public static void SaveData<T>(string fileName, T dataToSave)
{
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
try
{
if (store.FileExists(fileName))
{
store.DeleteFile(fileName);
}
using (IsolatedStorageFileStream stream = store.OpenFile(fileName, System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
var serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(stream, dataToSave);
}
}
catch (Exception e)
{
//MessageBox.Show(e.Message);
return;
}
}
}
public static T ReadData<T>(string fileName)
{
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.FileExists(fileName))
{
using (IsolatedStorageFileStream stream = store.OpenFile(fileName, FileMode.OpenOrCreate, FileAccess.Read))
{
try
{
var serializer = new DataContractSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
}
catch (Exception)
{
return default(T);
}
}
}
return default(T);
}
}
}
Saving Data in ISO Store
public ObservableCollection<CustomClass> AllEvents = new public ObservableCollection<CustomClass>();
//AllEvents.Add(customclassref1);
//AllEvents.Add(customclassref2);
//AllEvents.Add(customclassref3);
SerializeHelper.SaveData<ObservableCollection<CustomClass>>("AllEvents", AllEvents);
Retrieving Data from ISO store
AllEvents = (ObservableCollection<CustomClass>)SerializeHelper.ReadData<ObservableCollection<CustomClass>>("AllEvents");

Categories

Resources