diff --git a/Blazored.LocalStorage.sln b/Blazored.LocalStorage.sln index 9f3a6ee..57b05c6 100644 --- a/Blazored.LocalStorage.sln +++ b/Blazored.LocalStorage.sln @@ -13,7 +13,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorServerSide", "samples EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9170D7A9-70CE-48E3-88A3-F11D2983103E}" ProjectSection(SolutionItems) = preProject - azure-pipelines.yml = azure-pipelines.yml README.md = README.md EndProjectSection EndProject diff --git a/README.md b/README.md index e804c22..21eba84 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Blazored LocalStorage A library to provide access to local storage in Blazor applications -[![Build Status](https://dev.azure.com/blazored/LocalStorage/_apis/build/status/Blazored.LocalStorage?branchName=master)](https://dev.azure.com/blazored/LocalStorage/_build/latest?definitionId=1&branchName=master) +![Build & Test Main](https://github.com/Blazored/LocalStorage/workflows/Build%20&%20Test%20Main/badge.svg) [![Nuget](https://img.shields.io/nuget/v/blazored.localstorage.svg)](https://www.nuget.org/packages/Blazored.LocalStorage/) @@ -121,6 +121,7 @@ The APIs available are: - asynchronous via `ILocalStorageService`: - SetItemAsync() - GetItemAsync() + - GetItemAsStringAsync() - RemoveItemAsync() - ClearAsync() - LengthAsync() @@ -130,10 +131,13 @@ The APIs available are: - synchronous via `ISyncLocalStorageService` (Synchronous methods are **only** available in Blazor WebAssembly): - SetItem() - GetItem() + - GetItemAsString() - RemoveItem() - Clear() - Length() - Key() - ContainsKey() -**Note:** Blazored.LocalStorage methods will handle the serialisation and de-serialisation of the data for you. +**Note:** Blazored.LocalStorage methods will handle the serialisation and de-serialisation of the data for you, the exception is the `GetItemAsString[Async]` method. + +If you want to handle serialising and de-serialising yourself, serialise the data to a string and save using the `SetItem[Async]` method, as normal -- This method will not attempt to serialise a string value. You can then read out the data using the `GetItemAsString[Async]` method and de-serialise it yourself. diff --git a/samples/BlazorWebAssembly/Pages/Index.razor b/samples/BlazorWebAssembly/Pages/Index.razor index 70ebe93..9e6d3ae 100644 --- a/samples/BlazorWebAssembly/Pages/Index.razor +++ b/samples/BlazorWebAssembly/Pages/Index.razor @@ -103,7 +103,7 @@ async Task GetStringFromLocalStorage() { - StringFromLocalStorage = await localStorage.GetStringAsync("name"); + StringFromLocalStorage = await localStorage.GetItemAsStringAsync("name"); if (string.IsNullOrEmpty(StringFromLocalStorage)) { diff --git a/samples/BlazorWebAssembly/Pages/Sync.razor b/samples/BlazorWebAssembly/Pages/Sync.razor index aef91d5..8d9d311 100644 --- a/samples/BlazorWebAssembly/Pages/Sync.razor +++ b/samples/BlazorWebAssembly/Pages/Sync.razor @@ -100,7 +100,7 @@ void GetStringFromLocalStorage() { - StringFromLocalStorage = localStorage.GetString("name"); + StringFromLocalStorage = localStorage.GetItemAsString("name"); if (string.IsNullOrEmpty(StringFromLocalStorage)) { diff --git a/src/Blazored.LocalStorage/ILocalStorageService.cs b/src/Blazored.LocalStorage/ILocalStorageService.cs index 38df59d..cb5c9ab 100644 --- a/src/Blazored.LocalStorage/ILocalStorageService.cs +++ b/src/Blazored.LocalStorage/ILocalStorageService.cs @@ -5,27 +5,61 @@ namespace Blazored.LocalStorage { public interface ILocalStorageService { - Task ClearAsync(); + /// + /// Clears all data from local storage. + /// + /// A representing the completion of the operation. + ValueTask ClearAsync(); - Task GetItemAsync(string key); + /// + /// Retrieve the specified data from local storage and deseralise it to the specfied type. + /// + /// A value specifying the name of the local storage slot to use + /// A representing the completion of the operation. + ValueTask GetItemAsync(string key); - Task GetStringAsync(string key); + /// + /// Retrieve the specified data from local storage as a . + /// + /// A value specifying the name of the storage slot to use + /// A representing the completion of the operation. + ValueTask GetItemAsStringAsync(string key); - Task KeyAsync(int index); + /// + /// Return the name of the key at the specified . + /// + /// + /// A representing the completion of the operation. + ValueTask KeyAsync(int index); /// - /// Checks if the key exists in local storage but does not check the value. + /// Checks if the exists in local storage, but does not check its value. /// - /// name of the key - /// True if the key exist, false otherwise - Task ContainKeyAsync(string key); - - Task LengthAsync(); + /// A value specifying the name of the storage slot to use + /// A representing the completion of the operation. + ValueTask ContainKeyAsync(string key); - Task RemoveItemAsync(string key); + /// + /// The number of items stored in local storage. + /// + /// A representing the completion of the operation. + ValueTask LengthAsync(); - Task SetItemAsync(string key, T data); + /// + /// Remove the data with the specified . + /// + /// A value specifying the name of the storage slot to use + /// A representing the completion of the operation. + ValueTask RemoveItemAsync(string key); + /// + /// Sets or updates the in local storage with the specified . + /// + /// A value specifying the name of the storage slot to use + /// The data to be saved + /// A representing the completion of the operation. + ValueTask SetItemAsync(string key, T data); + event EventHandler Changing; event EventHandler Changed; } diff --git a/src/Blazored.LocalStorage/ISyncLocalStorageService.cs b/src/Blazored.LocalStorage/ISyncLocalStorageService.cs index 674a638..f21fefc 100644 --- a/src/Blazored.LocalStorage/ISyncLocalStorageService.cs +++ b/src/Blazored.LocalStorage/ISyncLocalStorageService.cs @@ -4,25 +4,56 @@ namespace Blazored.LocalStorage { public interface ISyncLocalStorageService { + /// + /// Clears all data from local storage. + /// void Clear(); + /// + /// Retrieve the specified data from local storage as a . + /// + /// A value specifying the name of the local storage slot to use + /// The data from the specified as a T GetItem(string key); - - string GetString(string key); + /// + /// Retrieve the specified data from local storage as a . + /// + /// A value specifying the name of the storage slot to use + /// The data associated with the specified as a + string GetItemAsString(string key); + + /// + /// Return the name of the key at the specified . + /// + /// + /// The name of the key at the specified string Key(int index); /// - /// Checks if the key exists in local storage but does not check the value. + /// Checks if the exists in local storage, but does not check its value. /// - /// name of the key - /// True if the key exist, false otherwise + /// A value specifying the name of the storage slot to use + /// Boolean indicating if the specified exists bool ContainKey(string key); + /// + /// The number of items stored in local storage. + /// + /// The number of items stored in local storage int Length(); + /// + /// Remove the data with the specified . + /// + /// A value specifying the name of the storage slot to use void RemoveItem(string key); + /// + /// Sets or updates the in local storage with the specified . + /// + /// A value specifying the name of the storage slot to use + /// The data to be saved void SetItem(string key, T data); event EventHandler Changing; diff --git a/src/Blazored.LocalStorage/LocalStorageService.cs b/src/Blazored.LocalStorage/LocalStorageService.cs index 874d72a..99511b7 100644 --- a/src/Blazored.LocalStorage/LocalStorageService.cs +++ b/src/Blazored.LocalStorage/LocalStorageService.cs @@ -20,7 +20,7 @@ public LocalStorageService(IJSRuntime jSRuntime, IOptions o _jSInProcessRuntime = jSRuntime as IJSInProcessRuntime; } - public async Task SetItemAsync(string key, T data) + public async ValueTask SetItemAsync(string key, T data) { if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key)); @@ -43,7 +43,7 @@ public async Task SetItemAsync(string key, T data) RaiseOnChanged(key, e.OldValue, data); } - public async Task GetItemAsync(string key) + public async ValueTask GetItemAsync(string key) { if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key)); @@ -65,7 +65,7 @@ public async Task GetItemAsync(string key) } } - public async Task GetStringAsync(string key) + public async ValueTask GetItemAsStringAsync(string key) { if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key)); @@ -73,7 +73,7 @@ public async Task GetStringAsync(string key) return await _jSRuntime.InvokeAsync("localStorage.getItem", key); } - public async Task RemoveItemAsync(string key) + public async ValueTask RemoveItemAsync(string key) { if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key)); @@ -81,13 +81,13 @@ public async Task RemoveItemAsync(string key) await _jSRuntime.InvokeVoidAsync("localStorage.removeItem", key); } - public async Task ClearAsync() => await _jSRuntime.InvokeVoidAsync("localStorage.clear"); + public async ValueTask ClearAsync() => await _jSRuntime.InvokeVoidAsync("localStorage.clear"); - public async Task LengthAsync() => await _jSRuntime.InvokeAsync("eval", "localStorage.length"); + public async ValueTask LengthAsync() => await _jSRuntime.InvokeAsync("eval", "localStorage.length"); - public async Task KeyAsync(int index) => await _jSRuntime.InvokeAsync("localStorage.key", index); + public async ValueTask KeyAsync(int index) => await _jSRuntime.InvokeAsync("localStorage.key", index); - public async Task ContainKeyAsync(string key) => await _jSRuntime.InvokeAsync("localStorage.hasOwnProperty", key); + public async ValueTask ContainKeyAsync(string key) => await _jSRuntime.InvokeAsync("localStorage.hasOwnProperty", key); public void SetItem(string key, T data) { @@ -138,7 +138,7 @@ public T GetItem(string key) return (T)(object)serialisedData; } } - public string GetString(string key) + public string GetItemAsString(string key) { if (string.IsNullOrEmpty(key)) @@ -208,27 +208,6 @@ private async Task RaiseOnChangingAsync(string key, object da return e; } - private async Task GetItemInternalAsync(string key) - { - if (string.IsNullOrEmpty(key)) - throw new ArgumentNullException(nameof(key)); - - var serialisedData = await _jSRuntime.InvokeAsync("localStorage.getItem", key); - - if (string.IsNullOrWhiteSpace(serialisedData)) - return default; - - if (serialisedData.StartsWith("{") && serialisedData.EndsWith("}") - || serialisedData.StartsWith("\"") && serialisedData.EndsWith("\"")) - { - return JsonSerializer.Deserialize(serialisedData, _jsonOptions); - } - else - { - return (T)(object)serialisedData; - } - } - private ChangingEventArgs RaiseOnChangingSync(string key, object data) { var e = new ChangingEventArgs @@ -243,15 +222,12 @@ private ChangingEventArgs RaiseOnChangingSync(string key, object data) return e; } - public T GetItemInternal(string key) + private async Task GetItemInternalAsync(string key) { if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key)); - if (_jSInProcessRuntime == null) - throw new InvalidOperationException("IJSInProcessRuntime not available"); - - var serialisedData = _jSInProcessRuntime.Invoke("localStorage.getItem", key); + var serialisedData = await _jSRuntime.InvokeAsync("localStorage.getItem", key); if (string.IsNullOrWhiteSpace(serialisedData)) return default; @@ -267,7 +243,7 @@ public T GetItemInternal(string key) } } - public object GetItemInternal(string key) + private object GetItemInternal(string key) { if (string.IsNullOrEmpty(key)) throw new ArgumentNullException(nameof(key));