Skip to content

Value cannot be null #3

Open
Open

Description

@cedric56

In linux, it happens when it try to launch the SecureLocalStorage with the default config

var config = new DefaultLocalStorageConfig();
var secureStorage = new SecureLocalStorage.SecureLocalStorage(config);

Image

Une exception non gérée du type 'System.ArgumentNullException' s'est produite dans Avalonia.Base.dll: 'Value cannot be null.'
Trace de la pile :
 >   à Newtonsoft.Json.Utilities.ValidationUtils.ArgumentNotNull(Object value, String parameterName)
 >   à Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
 >   à Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
 >   à Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)
 >   à SecureLocalStorage.SecureLocalStorage.Read()
 >   à SecureLocalStorage.SecureLocalStorage..ctor(ISecureLocalStorageConfig configuration)

Activity

  1. haraldwer commented on Aug 4, 2025

    @haraldwer

    @cedric56 Did you figure out a workaround?

  2. cedric56 commented on Aug 4, 2025

    @cedric56
    Author

    @haraldwer yes, i have created a SecureLocalStorageEx

    public class SecureLocalStorageEx
    {
        internal ISecureLocalStorageConfig Config { get; }
    
        internal Dictionary<string, string> StoredData { get; set; }
    
        private byte[] Key { get; }
    
        public int Count => StoredData.Count;
    
        internal void CreateIfNotExists(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }
    
        public SecureLocalStorageEx(ISecureLocalStorageConfig configuration)
        {
            Config = configuration ?? throw new ArgumentNullException("configuration");
            CreateIfNotExists(Config.StoragePath);
            Key = Encoding.UTF8.GetBytes(Config.BuildLocalSecureKey());
            Read();
        }
    
        internal byte[] EncryptData(string data, byte[] key, DataProtectionScope scope)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
    
            if (data.Length <= 0)
            {
                throw new ArgumentException("data");
            }
    
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
    
            if (key.Length == 0)
            {
                throw new ArgumentException("key");
            }
    
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                return ProtectedData.Protect(Encoding.UTF8.GetBytes(data), key, scope);
            }
    
            return Encoding.UTF8.GetBytes(AESThenHMAC.SimpleEncryptWithPassword(data, Encoding.UTF8.GetString(key)));
        }
    
        internal string DecryptData(byte[] data, byte[] key, DataProtectionScope scope)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
    
            if (data.Length == 0)
            {
                throw new ArgumentException("data");
            }
    
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
    
            if (key.Length == 0)
            {
                throw new ArgumentException("key");
            }
    
            return AESThenHMAC.SimpleDecryptWithPassword(Encoding.UTF8.GetString(data), Encoding.UTF8.GetString(key));
        }
    
        internal void Read()
        {
            var path = Path.Combine(Config.StoragePath, "default");
            if (File.Exists(path))
            {
                var data = DecryptData(File.ReadAllBytes(path), Key, DataProtectionScope.LocalMachine);
                if (!string.IsNullOrWhiteSpace(data))
                {
                    StoredData = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
                    return;
                }
            }
    
            StoredData = new Dictionary<string, string>();
        }
    
        internal void Write()
        {
            File.WriteAllBytes(Path.Combine(Config.StoragePath, "default"), EncryptData(JsonConvert.SerializeObject(StoredData), Key, DataProtectionScope.LocalMachine));
            Read();
        }
    
        public void Clear()
        {
            File.Delete(Path.Combine(Config.StoragePath, "default"));
            Read();
        }
    
        public bool Exists()
        {
            return File.Exists(Path.Combine(Config.StoragePath, "default"));
        }
    
        public bool Exists(string key)
        {
            return StoredData.ContainsKey(key);
        }
    
        public string Get(string key)
        {
            if (StoredData.TryGetValue(key, out var value))
            {
                return JsonConvert.DeserializeObject<string>(value ?? string.Empty);
            }
    
            return null!;
        }
    
        public T Get<T>(string key)
        {
            if (StoredData.TryGetValue(key, out var value))
            {
                return JsonConvert.DeserializeObject<T>(value ?? string.Empty);
            }
    
            return default(T);
        }
    
        public IReadOnlyCollection<string> Keys()
        {
            return StoredData.Keys;
        }
    
        public void Remove(string key)
        {
            StoredData.Remove(key);
            Write();
        }
    
        public void Set<T>(string key, T data)
        {
            if (Exists(key))
            {
                Remove(key);
            }
    
            StoredData.Add(key, JsonConvert.SerializeObject(data));
            Write();
        }
    }
    

    I use it like that

    var config = new DefaultLocalStorageConfig();
    storageEx = new SecureLocalStorageEx(config);
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions