Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to serialize Windows.Storage.StorageFile in metro app

I'm developing a music metro style app. I'm getting all music files from users music library I want to store StorageFile object, because i don't want to retrieve again and again.To do this i tried serialize StorageFile object and store it into XML. From the examples here and here i tried to generate XML file, but it throws an exception on creating XML file saying

Type 'Windows.Storage.StorageFile' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.

So far my code is below,

namespace CloudMusic.AppSettings
{
    [KnownType(typeof(CloudMusic.AppSettings.MusicFileDict))]
    [DataContractAttribute]
    public class MusicFileDict
    {
        [DataMember]
        public object musicStorageFile { get; set; }

        [DataMember]
        public int id { get; set; }
    }
}

and from below class I'm generating XML

class GenerateMusicDict
{    
        private const string filename = "musiclist.xml";
        static private List<MusicFileDict> _data = new List<MusicFileDict>();

        static public List<MusicFileDict> Data
        {
            get { return _data; }
        }
        static async public Task Save<T>()
        {
            await Windows.System.Threading.ThreadPool.RunAsync((sender) => GenerateMusicDict.SaveAsync<T>().Wait(), Windows.System.Threading.WorkItemPriority.Normal);
        }        

        internal static async Task SaveAsync<T>()
        {           
            GenerateMusicDict.GenerateMusicFileDict();           
            try
            {
                StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
                IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite);
                IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);

                var sessionSerializer = new DataContractSerializer(typeof(List<MusicFileDict>), new Type[] { typeof(T) });
                sessionSerializer.WriteObject(sessionOutputStream.AsStreamForWrite(), _data);
                await sessionOutputStream.FlushAsync();
            }
            catch (Exception)
            {
            }

        }
        /// <summary>
        /// Generate music file dictonary according to songs ID
        /// </summary>
        /// <param name="musicFileList"></param>
        private static void GenerateMusicFileDict()
        {
            List<StorageFile> music_file_list = MusicFileDict.GetMusicList(); // At this stage i'll get all my music files,GetMusicList() function returns List<StorageFile>
            for (int i = 0; i < music_file_list.Count; i++)
            {
                _data.Add(new MusicFileDict { id = i, musicStorageFile = music_file_list[i]});          
            } 
        }
}

and calling Save method from my main class using

 await GenerateMusicDict.Save<MusicFileDict>(); 

On SaveAsync() function at this line

 sessionSerializer.WriteObject(sessionOutputStream.AsStreamForWrite(), _data);

it's firing an Exception saying

Type 'Windows.Storage.StorageFile' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types. so how can i serialize it? or is there any way that i can store it and re-use. Please help me

like image 912
Raj Kumar Avatar asked Dec 23 '12 09:12

Raj Kumar


1 Answers

Make use of the FutureAccessList http://msdn.microsoft.com/library/windows/apps/BR207457 it should provide the functionality you're looking for.

You can retrieve and access the files by referencing their paths. These paths can easily be stored and serialized (for example as a List).

This also alleviates any permissions issues you might run into if you want your app to be able to access user content that is outside of the Music Library.

like image 154
Kellen Avatar answered Sep 28 '22 03:09

Kellen