Search code examples
xamarinxamarin.formsuwpxlabs

XLabs.Platform not working on UWP


I am using Windows 10 & Visual Studio 2015 for development and targeting Android, iOS, Windows Phone, Windows Universal.

I wanted to use XLabs SecureStorage Service.

I am using XLabs.Platform package 2.3.0-pre02.

at this line i am getting exception (only for UWP)

secureStorage.Store(key, Encoding.UTF8.GetBytes(value));

And Exception Details are :

FileName : System.Runtime.WindowsRuntime, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

HResult : -2146234304

HelpLink : null

InnerException : null

Message : Could not load file or assembly 'System.Runtime.WindowsRuntime, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Source : XLabs.Platform.UWP

SourceTrack : at XLabs.Platform.Services.SecureStorage.d__6.MoveNext() at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.StartTStateMachine at XLabs.Platform.Services.SecureStorage.Store(String key, Byte[] dataBytes) at UWPTest.SecureStorageService.Store(String key, String value, Boolean overwrite)


Solution

  • After some trial and error i am able to run SecureStorage service successfully on Xamarin UWP.

    SecureStorage.cs(Code)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ABC.UWP.Common
    {
         using System;
         using System.IO;
         using Windows.Storage;
         using System.Threading;
         using System.Runtime.InteropServices.WindowsRuntime;
         using XLabs.Platform.Services;
         using Windows.Security.Cryptography.DataProtection;
    
         /// <summary>
         /// Implements <see cref="ISecureStorage"/> for WP using <see cref="IsolatedStorageFile"/> and <see cref="ProtectedData"/>.
         /// </summary>
         public class SecureStorage : ISecureStorage
         {
             private static Windows.Storage.ApplicationData AppStorage { get { return ApplicationData.Current; } }
    
             private static Windows.Security.Cryptography.DataProtection.DataProtectionProvider _dataProtectionProvider = new DataProtectionProvider();
    
             private readonly byte[] _optionalEntropy;
    
             /// <summary>
             /// Initializes a new instance of <see cref="SecureStorage"/>.
             /// </summary>
             /// <param name="optionalEntropy">Optional password for additional entropy to make encyption more complex.</param>
             public SecureStorage(byte[] optionalEntropy)
             {
                 this._optionalEntropy = optionalEntropy;
             }
    
             /// <summary>
             /// Initializes a new instance of <see cref="SecureStorage"/>.
             /// </summary>
             public SecureStorage() : this(null)
             {
    
             }
    
             #region ISecureStorage Members
    
             /// <summary>
             /// Stores the specified key.
             /// </summary>
             /// <param name="key">The key.</param>
             /// <param name="dataBytes">The data bytes.</param>
             public async void Store(string key, byte[] dataBytes)
             {
                 //var mutex = new Mutex(false, key);
                 using (var mutex = new Mutex(false, key))
                 {
                     try
                     {
                         mutex.WaitOne();
    
                         var buffer = dataBytes.AsBuffer();
    
                         if (_optionalEntropy != null)
                         {
                             buffer = await _dataProtectionProvider.ProtectAsync(buffer);
                         }
    
                         var file = await AppStorage.LocalFolder.CreateFileAsync(key, CreationCollisionOption.ReplaceExisting);
    
                         await FileIO.WriteBufferAsync(file, buffer);
                     }
                     catch (Exception ex)
                     {
                         throw new Exception(string.Format("No entry found for key {0}.", key), ex);
                     }
                 }
                 //finally
                 //{
                 //    mutex.ReleaseMutex();
                 //}
             }
    
             /// <summary>
             /// Retrieves the specified key.
             /// </summary>
             /// <param name="key">The key.</param>
             /// <returns>System.Byte[].</returns>
             /// <exception cref="System.Exception"></exception>
             public byte[] Retrieve(string key)
             {
                 var mutex = new Mutex(false, key);
    
                 try
                 {
                     mutex.WaitOne();
    
                     return Task.Run(async () =>
                     {
                         var file = await AppStorage.LocalFolder.GetFileAsync(key);
                         var buffer = await FileIO.ReadBufferAsync(file);
                         if (_optionalEntropy != null)
                         {
                             buffer = _dataProtectionProvider.UnprotectAsync(buffer).GetResults();
                         }
                         return buffer.ToArray();
                     }).Result;
                 }
                 catch (Exception ex)
                 {
                     throw new Exception(string.Format("No entry found for key {0}.", key), ex);
                 }
                 finally
                 {
                     mutex.ReleaseMutex();
                 }
             }
    
             /// <summary>
             /// Deletes the specified key.
             /// </summary>
             /// <param name="key">The key.</param>
             public void Delete(string key)
             {
                 var mutex = new Mutex(false, key);
    
                 try
                 {
                     mutex.WaitOne();
    
                     Task.Run(async () =>
                     {
                         var file = await AppStorage.LocalFolder.GetFileAsync(key);
                         await file.DeleteAsync();
                     });
                 }
                 finally
                 {
                     mutex.ReleaseMutex();
                 }
             }
    
             /// <summary>
             /// Checks if the storage contains a key.
             /// </summary>
             /// <param name="key">The key to search.</param>
             /// <returns>True if the storage has the key, otherwise false.     </returns>
             public bool Contains(string key)
             {
                 try
                 {
                     return Task.Run(async() => await  AppStorage.LocalFolder.GetFileAsync(key)).Result.IsAvailable;
                 }
                 catch
                 {
                     return false;
                 }
             }
             #endregion
         }
     }