Did the DataContractSerializer change in RTM?
-
Saturday, August 18, 2012 1:57 PM
After installing the Win8 and VS2012 RTM bits my Serialize method throws an exception. It complains of needing a list of knowntypes. Before RTM, I could easily pass in the type I was expecting to serialize.
Here is the code that used to work:
public async Task SerializeDataSetAsync() { StorageFolder storageFolder = ApplicationData.Current.LocalFolder; StorageFile sfCats = await storageFolder.CreateFileAsync(this.InvFileName, CreationCollisionOption.ReplaceExisting); var dcs = new DataContractSerializer(typeof(ObservableCollection<Category>)); using (IRandomAccessStream raStream1 = await sfCats.OpenAsync(FileAccessMode.ReadWrite)) { dcs.WriteObject(raStream1.AsStream(), this); } }When I add a list of knowntypes, it still blows.
public async Task SerializeDataSetAsync() { StorageFolder storageFolder = ApplicationData.Current.LocalFolder; StorageFile sfCats = await storageFolder.CreateFileAsync(this.InvFileName, CreationCollisionOption.ReplaceExisting); List<Type> knownTypes = new List<Type>(); knownTypes.Add(typeof(Category)); knownTypes.Add(typeof(Item)); var dcs = new DataContractSerializer(typeof(ObservableCollection<Category>), knownTypes); using (IRandomAccessStream raStream1 = await sfCats.OpenAsync(FileAccessMode.ReadWrite)) { dcs.WriteObject(raStream1.AsStream(), this); } }
Thanks, Terrence
All Replies
-
Saturday, August 18, 2012 3:16 PM
So maybe dont use AsStreamthis worked fine for me in RTM
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("ewwe", CreationCollisionOption.ReplaceExisting); using (var stream = await file.OpenStreamForWriteAsync()) { Dictionary<string, object> dictonary = new Dictionary<string, object>(); dictonary.Add("hello", "hello"); var knownTypes = dictonary.Values.Select(x => x.GetType()).Distinct().ToArray(); DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), knownTypes); serializer.WriteObject(stream, dictonary); await stream.FlushAsync(); } But all objects
-
Saturday, August 18, 2012 4:59 PM
The following is a RTM solution that does not require 'knownTypes':
<Page x:Class="ForInfo2.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:ForInfo2" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <StackPanel> <Button Content="Serialize" Click="Button_Click_1"/> <Button Content="Deserialize" Click="Button_Click_2"/> <TextBox Text="{Binding Date}" Width="300" IsReadOnly="True" HorizontalAlignment="Left" /> <ListView x:Name="lv" Width="300" Height="600" HorizontalAlignment="Left" Background="LightBlue" ItemsSource="{Binding ItemsSource}"> <ListView.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="*** Category ***"/> <TextBlock Text="{Binding Path=Id}"/> <TextBlock Text="{Binding Path=Name}"/> <TextBlock Text="{Binding Path=ItemList[0].Id}"/> <TextBlock Text="--- Item ---"/> <TextBlock Text="{Binding Path=Item.Id}"/> <TextBlock Text="{Binding Path=Item.Name}"/> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackPanel> </Grid> </Page>---
using System; using System.Collections.ObjectModel; using System.ComponentModel; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; namespace ForInfo2 { /// <summary> /// /// </summary> public sealed partial class MainPage : Page, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } private readonly ObservableCollection<Category> itemsSource = new ObservableCollection<Category>(); public ObservableCollection<Category> ItemsSource { get { return itemsSource; } } string date; public string Date { get { return date; } set { date = value; OnPropertyChanged("Date"); } } public MainPage() { this.DataContext = this; this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { } static int offset = 1; private async void Button_Click_1(object sender, RoutedEventArgs e) { Item item; Category category; // Exec this.Date = DateTime.Now.ToString("hh.mm.ss"); for (int i = 1; i < 5; i++) { category = new Category() { Id = offset, Name = String.Format("CatgName:{0}", offset++) }; item = new Item() { Id = offset, Name = String.Format("ItemName:{0} {1}", offset++, this.Date) }; category.Item = item; category.ItemList.Add(item); category.ItemList.Add(item); SerialData.List.Add(category); } // ... await SerialExec.Save(); } private async void Button_Click_2(object sender, RoutedEventArgs e) { // Exec await SerialExec.Restore(); // ... foreach (Category item in SerialData.List) { itemsSource.Add(item); lv.ScrollIntoView(item); } } } }---
using System.Collections.ObjectModel; namespace ForInfo2 { public class SerialData { private static ObservableCollection<Category> list = new ObservableCollection<Category>(); public static ObservableCollection<Category> List { get { return list; } set { list = value; } } } }using System; using System.Collections.ObjectModel; using System.IO; using System.Runtime.Serialization; using System.Threading.Tasks; using Windows.Storage; using Windows.Storage.Streams; namespace ForInfo2 { public class SerialExec { private static StorageFolder folder = ApplicationData.Current.LocalFolder; private const string fileName = "Category.xml"; /// <summary> /// /// </summary> static async public Task Save() { StorageFile sessionFile = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(ObservableCollection<Category>)); // ... using (IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite)) { sessionSerializer.WriteObject(sessionRandomAccess.AsStream(), SerialData.List); } } /// <summary> /// /// </summary> static async public Task Restore() { StorageFile sessionFile = await folder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists); if (sessionFile == null) return; // ... IInputStream sessionInputStream = await sessionFile.OpenReadAsync(); DataContractSerializer sessionSerializer = new DataContractSerializer(typeof(ObservableCollection<Category>)); SerialData.List = (ObservableCollection<Category>)sessionSerializer.ReadObject(sessionInputStream.AsStreamForRead()); } } }---
using System; using System.Collections.Generic; using System.Runtime.Serialization; namespace ForInfo2 { [KnownType(typeof(Category))] [DataContract(Name = "Category", Namespace = "http://www.mySelf.com")] public class Category { [DataMember()] public int Id { get; set; } [DataMember()] public String Name { get; set; } [DataMember()] public Item Item { get; set; } [DataMember()] public IList<Item> ItemList { get; set; } public Category() { this.ItemList = new List<Item>(); } } }---
using System; using System.Runtime.Serialization; namespace ForInfo2 { [KnownType(typeof(Item))] [DataContract(Name = "Item", Namespace = "http://www.mySelf.com")] public class Item { [DataMember()] public int Id { get; set; } [DataMember()] public String Name { get; set; } } }
- Edited by ForInfoMicrosoft Community Contributor Saturday, August 18, 2012 5:01 PM
-
Saturday, August 18, 2012 5:07 PMi agree knownTypes shouldnt be nessary.. in webradio not using it neither
-
Saturday, August 18, 2012 6:49 PM
So here is the message.
Message=Type 'NVIN.DataModel.ViewModel' with data contract name
'ViewModel:http://schemas.datacontract.org/2004/07/NVIN.DataModel' is not expected.
I am not serializing the ViewModel. My serialzier code is in my ViewModel class and the I an serializing a collection on the ViewModel.
Thanks, Terrence
-
Saturday, August 18, 2012 6:53 PM
the method you showed is in your viewmodel?
you have this:
dcs.WriteObject(raStream1.AsStream(), this);
so you are serializing the viewmodel then (this == the viewmodel)- Marked As Answer by Terrence_ Saturday, August 18, 2012 7:32 PM
-
Saturday, August 18, 2012 7:32 PM
Dave thanks so much for inspecting my code so closely. I was going to serialize the whole ViewModel, but changed back to serializing just the collection and I forgot to change that from this to this.Categories.
I wish I could buy you a beer.
And thank you for the pdf of the document.
Thanks, Terrence
-
Saturday, August 18, 2012 7:32 PMThank you for your great post of code, it helped me a bunch.
Thanks, Terrence


