XLabs.Platform 不适用于 UWP

XLabs.Platform not working on UWP

我正在使用 Windows 10 & Visual Studio 2015 进行开发和定位 Android、iOS、Windows Phone、Windows 通用。

我想使用 XLabs SecureStorage 服务。

我正在使用 XLabs.Platform 包 2.3.0-pre02.

在这一行我遇到异常(仅适用于 UWP)

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

异常详细信息为:

文件名:System.Runtime.WindowsRuntime,版本=4.0.11.0,文化=中性,PublicKeyToken=b77a5c561934e089

HResult : -2146234304

帮助链接:空

InnerException : 空

Message:无法加载文件或程序集 'System.Runtime.WindowsRuntime, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' 或其依赖项之一。找到的程序集的清单定义与程序集引用不匹配。 (HRESULT 异常:0x80131040)

来源 : XLabs.Platform.UWP

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

经过反复试验,我能够在 Xamarin UWP 上成功 运行 SecureStorage 服务。

SecureStorage.cs(代码)

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
     }
 }