diff --git a/EasyCaching.sln b/EasyCaching.sln
index bfd9e15d..a595298f 100644
--- a/EasyCaching.sln
+++ b/EasyCaching.sln
@@ -68,6 +68,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bus", "bus", "{B337509B-75F
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyCaching.LiteDB", "src\EasyCaching.LiteDB\EasyCaching.LiteDB.csproj", "{BA850294-3103-4540-8A27-FC768E1DC8FC}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyCaching.Serialization.SystemTextJson", "serialization\EasyCaching.Serialization.SystemTextJson\EasyCaching.Serialization.SystemTextJson.csproj", "{4FCF16BF-5E21-4B74-AB45-3C121ADF1485}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -178,6 +180,10 @@ Global
{BA850294-3103-4540-8A27-FC768E1DC8FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA850294-3103-4540-8A27-FC768E1DC8FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA850294-3103-4540-8A27-FC768E1DC8FC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4FCF16BF-5E21-4B74-AB45-3C121ADF1485}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4FCF16BF-5E21-4B74-AB45-3C121ADF1485}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4FCF16BF-5E21-4B74-AB45-3C121ADF1485}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4FCF16BF-5E21-4B74-AB45-3C121ADF1485}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -209,6 +215,7 @@ Global
{43AD80E9-696B-4042-9D50-B26F48BE1928} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9}
{711603E1-8363-4F8D-9AA9-8C03EC8BD35F} = {B4241D34-A973-4A13-BD89-9BAE3F2BDDF6}
{BA850294-3103-4540-8A27-FC768E1DC8FC} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9}
+ {4FCF16BF-5E21-4B74-AB45-3C121ADF1485} = {15070C49-A507-4844-BCFE-D319CFBC9A63}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {63A57886-054B-476C-AAE1-8D7C8917682E}
diff --git a/build/releasenotes.props b/build/releasenotes.props
index de977ee8..eaa7fb1d 100644
--- a/build/releasenotes.props
+++ b/build/releasenotes.props
@@ -1,14 +1,14 @@
- 1. IRedisProvider support search keys.
- 2. DefaultEasyCachingKeyGenerator support GenerateCacheKeyForModel.
+ 1. Allow to cache null value.
+ 2. Ready for 1.x version.
1. Upgrading dependencies.
- 1. IRedisProvider support search keys.
+ 1. Upgrading dependencies.
1. Upgrading dependencies.
@@ -38,7 +38,7 @@
1. Upgrading dependencies.
- 1. IRedisProvider support search keys.
+ 1. Upgrading dependencies.
1. Upgrading dependencies.
@@ -53,7 +53,10 @@
1. Upgrading dependencies.
- 1. LiteDB joined for the first time.
+ 1. Upgrading dependencies.
+
+ 1. Init.
+
diff --git a/build/version.props b/build/version.props
index 73a17b9c..63cef48f 100644
--- a/build/version.props
+++ b/build/version.props
@@ -1,23 +1,24 @@
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
- 0.9.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
+ 1.1.0
diff --git a/sample/EasyCaching.Demo.Interceptors/Controllers/ValuesController.cs b/sample/EasyCaching.Demo.Interceptors/Controllers/ValuesController.cs
index a7591e19..a973e71b 100644
--- a/sample/EasyCaching.Demo.Interceptors/Controllers/ValuesController.cs
+++ b/sample/EasyCaching.Demo.Interceptors/Controllers/ValuesController.cs
@@ -38,6 +38,11 @@ public string Aspectcore(int type = 1)
var res = _aService.GetDemo(111);
return $"{res.Id}-{res.Name}-{res.CreateTime}";
}
+ else if (type == 5)
+ {
+ var res = _aService.GetData();
+ return Newtonsoft.Json.JsonConvert.SerializeObject(res);
+ }
else
{
return "wait";
diff --git a/sample/EasyCaching.Demo.Interceptors/Services/IAspectCoreService.cs b/sample/EasyCaching.Demo.Interceptors/Services/IAspectCoreService.cs
index 2411b7e8..409056f6 100644
--- a/sample/EasyCaching.Demo.Interceptors/Services/IAspectCoreService.cs
+++ b/sample/EasyCaching.Demo.Interceptors/Services/IAspectCoreService.cs
@@ -27,6 +27,9 @@ public interface IAspectCoreService //: EasyCaching.Core.Internal.IEasyCaching
[EasyCachingAble(Expiration = 10)]
Demo GetDemo(int id);
+
+ [EasyCachingAble(Expiration = 10)]
+ object GetData();
}
public class AspectCoreService : IAspectCoreService
@@ -71,6 +74,10 @@ public string PutSomething(string str)
return str;
}
+ public object GetData()
+ {
+ return new { x = System.DateTimeOffset.Now.ToUnixTimeSeconds() };
+ }
}
[ProtoContract]
diff --git a/serialization/EasyCaching.Serialization.SystemTextJson/Configurations/EasyCachingJsonSerializerOptions.cs b/serialization/EasyCaching.Serialization.SystemTextJson/Configurations/EasyCachingJsonSerializerOptions.cs
new file mode 100644
index 00000000..63e80eb3
--- /dev/null
+++ b/serialization/EasyCaching.Serialization.SystemTextJson/Configurations/EasyCachingJsonSerializerOptions.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Encodings.Web;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace EasyCaching.Serialization.SystemTextJson.Configurations
+{
+ public class EasyCachingJsonSerializerOptions
+ {
+ ///
+ /// Gets or sets the encoder to use when escaping strings, or null to use the default
+ /// encoder.
+ ///
+ public JavaScriptEncoder Encoder => JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
+ ///
+ /// Gets or sets a value that defines how comments are handled during deserialization.
+ ///
+ public JsonCommentHandling ReadCommentHandling => JsonCommentHandling.Disallow;
+ ///
+ /// Gets or sets a value that specifies the policy used to convert a property's name
+ /// on an object to another format, such as camel-casing, or null to leave property
+ /// names unchanged.
+ ///
+ public JsonNamingPolicy PropertyNamingPolicy => null;
+ ///
+ /// Gets or sets a value that determines whether a property's name uses a case-insensitive
+ /// comparison during deserialization. The default value is false.
+ ///
+ public bool PropertyNameCaseInsensitive => false;
+ ///
+ /// Specifies how number types should be handled when serializing or deserializing.
+ ///
+ public JsonNumberHandling NumberHandling => JsonNumberHandling.Strict;
+ ///
+ /// Gets or sets the maximum depth allowed when serializing or deserializing JSON,
+ /// with the default value of 0 indicating a maximum depth of 64.
+ ///
+ public int MaxDepth => 0;
+ ///
+ /// Determines whether fields are handled serialization and deserialization. The
+ /// default value is false.
+ ///
+ public bool IncludeFields => false;
+ ///
+ /// Gets a value that determines whether read-only properties are ignored during
+ /// serialization. The default value is false.
+ ///
+ public bool IgnoreReadOnlyProperties => false;
+ ///
+ /// Determines whether read-only fields are ignored during serialization. A property
+ /// is read-only if it isn't marked with the readonly keyword. The default value is false.
+ ///
+ public bool IgnoreReadOnlyFields => false;
+ ///
+ /// Gets or sets a value that determines whether null values are ignored during serialization
+ /// and deserialization. The default value is false.
+ ///
+ public bool IgnoreNullValues = false;
+ ///
+ /// Gets or sets the policy used to convert a System.Collections.IDictionary key's
+ /// name to another format, such as camel-casing.
+ ///
+ public JsonNamingPolicy DictionaryKeyPolicy => null;
+ ///
+ /// Specifies a condition to determine when properties with default values are ignored
+ /// during serialization or deserialization. The default value is System.Text.Json.Serialization.JsonIgnoreCondition.Never.
+ ///
+ public JsonIgnoreCondition DefaultIgnoreCondition => JsonIgnoreCondition.Never;
+ ///
+ /// Gets or sets the default buffer size, in bytes, to use when creating temporary buffers.
+ ///
+ public int DefaultBufferSize => 16 * 1024;
+ ///
+ /// Gets the list of user-defined converters that were registered.
+ ///
+ public IList Converters => new List();
+ ///
+ /// Get or sets a value that indicates whether an extra comma at the end of a list
+ /// of JSON values in an object or array is allowed (and ignored) within the JSON
+ /// payload being deserialized.
+ ///
+ public bool AllowTrailingCommas => false;
+ ///
+ /// Configures how object references are handled when reading and writing JSON.
+ ///
+ public ReferenceHandler ReferenceHandler => null;
+ ///
+ /// Gets or sets a value that defines whether JSON should use pretty printing. By
+ /// default, JSON is serialized without any extra white space.
+ ///
+ public bool WriteIndented => false;
+ }
+}
diff --git a/serialization/EasyCaching.Serialization.SystemTextJson/Configurations/EasyCachingOptionsExtensions.cs b/serialization/EasyCaching.Serialization.SystemTextJson/Configurations/EasyCachingOptionsExtensions.cs
new file mode 100644
index 00000000..885572a2
--- /dev/null
+++ b/serialization/EasyCaching.Serialization.SystemTextJson/Configurations/EasyCachingOptionsExtensions.cs
@@ -0,0 +1,71 @@
+using EasyCaching.Core.Configurations;
+using System;
+using System.Linq;
+using System.Text.Json;
+
+namespace EasyCaching.Serialization.SystemTextJson.Configurations
+{
+
+ ///
+ /// EasyCaching options extensions.
+ ///
+ public static class EasyCachingOptionsExtensions
+ {
+ ///
+ /// Withs the json serializer.
+ ///
+ /// Options.
+ /// The name of this serializer instance.
+ public static EasyCachingOptions WithSystemTextJson(this EasyCachingOptions options, string name = "json") => options.WithSystemTextJson(configure: x => { }, name);
+
+ ///
+ /// Withs the json serializer.
+ ///
+ /// Options.
+ /// Configure serializer settings.
+ /// The name of this serializer instance.
+ public static EasyCachingOptions WithSystemTextJson(this EasyCachingOptions options, Action configure, string name)
+ {
+ var easyCachingJsonSerializerOptions = new EasyCachingJsonSerializerOptions();
+
+ configure(easyCachingJsonSerializerOptions);
+
+ void jsonSerializerSettings(JsonSerializerOptions x)
+ {
+ x.MaxDepth = easyCachingJsonSerializerOptions.MaxDepth;
+ x.AllowTrailingCommas = easyCachingJsonSerializerOptions.AllowTrailingCommas;
+ x.Converters.Union(easyCachingJsonSerializerOptions.Converters);
+ x.DefaultBufferSize = easyCachingJsonSerializerOptions.DefaultBufferSize;
+ x.DefaultIgnoreCondition = easyCachingJsonSerializerOptions.DefaultIgnoreCondition;
+ x.DictionaryKeyPolicy = easyCachingJsonSerializerOptions.DictionaryKeyPolicy;
+ x.Encoder = easyCachingJsonSerializerOptions.Encoder;
+ x.IgnoreReadOnlyFields = easyCachingJsonSerializerOptions.IgnoreReadOnlyFields;
+ x.IgnoreReadOnlyProperties = easyCachingJsonSerializerOptions.IgnoreReadOnlyProperties;
+ x.IncludeFields = easyCachingJsonSerializerOptions.IncludeFields;
+ x.NumberHandling = easyCachingJsonSerializerOptions.NumberHandling;
+ x.PropertyNameCaseInsensitive = easyCachingJsonSerializerOptions.PropertyNameCaseInsensitive;
+ x.PropertyNamingPolicy = easyCachingJsonSerializerOptions.PropertyNamingPolicy;
+ x.ReadCommentHandling = easyCachingJsonSerializerOptions.ReadCommentHandling;
+ x.ReferenceHandler = easyCachingJsonSerializerOptions.ReferenceHandler;
+ x.WriteIndented = easyCachingJsonSerializerOptions.WriteIndented;
+ }
+
+ options.RegisterExtension(new JsonOptionsExtension(name, jsonSerializerSettings));
+
+ return options;
+ }
+
+ ///
+ /// Withs the json serializer.
+ ///
+ /// Options.
+ /// Configure serializer settings.
+ /// The name of this serializer instance.
+ public static EasyCachingOptions WithSystemTextJson(this EasyCachingOptions options, Action jsonSerializerSettingsConfigure, string name)
+ {
+ options.RegisterExtension(new JsonOptionsExtension(name, jsonSerializerSettingsConfigure));
+
+ return options;
+ }
+ }
+}
\ No newline at end of file
diff --git a/serialization/EasyCaching.Serialization.SystemTextJson/Configurations/JsonOptionsExtension.cs b/serialization/EasyCaching.Serialization.SystemTextJson/Configurations/JsonOptionsExtension.cs
new file mode 100644
index 00000000..cf61886f
--- /dev/null
+++ b/serialization/EasyCaching.Serialization.SystemTextJson/Configurations/JsonOptionsExtension.cs
@@ -0,0 +1,51 @@
+using EasyCaching.Core.Configurations;
+using EasyCaching.Core.Serialization;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Text.Json;
+
+namespace EasyCaching.Serialization.SystemTextJson
+{
+ ///
+ /// Json options extension.
+ ///
+ internal sealed class JsonOptionsExtension : IEasyCachingOptionsExtension
+ {
+ ///
+ /// The name.
+ ///
+ private readonly string _name;
+
+ ///
+ /// The configure.
+ ///
+ private readonly Action _configure;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name.
+ /// Configure.
+ public JsonOptionsExtension(string name, Action configure)
+ {
+ _name = name;
+ _configure = configure;
+ }
+
+ public void AddServices(IServiceCollection services)
+ {
+ Action configure = x => { };
+
+ if (_configure != null) configure = _configure;
+
+ services.AddOptions();
+ services.Configure(_name, configure);
+ services.AddSingleton(x =>
+ {
+ var optionsMon = x.GetRequiredService>();
+ var options = optionsMon.Get(_name);
+ return new DefaultJsonSerializer(_name, options);
+ });
+ }
+ }
+}
diff --git a/serialization/EasyCaching.Serialization.SystemTextJson/DefaultJsonSerializer.cs b/serialization/EasyCaching.Serialization.SystemTextJson/DefaultJsonSerializer.cs
new file mode 100644
index 00000000..dc2a6b44
--- /dev/null
+++ b/serialization/EasyCaching.Serialization.SystemTextJson/DefaultJsonSerializer.cs
@@ -0,0 +1,118 @@
+using EasyCaching.Core.Internal;
+using EasyCaching.Core.Serialization;
+using System;
+using System.IO;
+using System.Text;
+using System.Text.Json;
+
+namespace EasyCaching.Serialization.SystemTextJson
+{
+ ///
+ /// Default json serializer.
+ ///
+ public class DefaultJsonSerializer : IEasyCachingSerializer
+ {
+ ///
+ /// The json serializer.
+ ///
+ private readonly JsonSerializerOptions jsonSerializerOption;
+ ///
+ /// The name.
+ ///
+ private readonly string _name;
+ ///
+ /// Gets the name.
+ ///
+ /// The name.
+ public string Name => _name;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Name.
+ /// serializerSettings.
+ public DefaultJsonSerializer(string name, JsonSerializerOptions serializerSettings)
+ {
+ _name = name;
+ jsonSerializerOption = serializerSettings;
+ }
+
+ ///
+ /// Deserialize the specified bytes.
+ ///
+ /// The deserialize.
+ /// Bytes.
+ /// The 1st type parameter.
+ public T Deserialize(byte[] bytes)
+ {
+ return JsonSerializer.Deserialize(bytes, jsonSerializerOption);
+ }
+ ///
+ /// Deserialize the specified bytes.
+ ///
+ /// The deserialize.
+ /// Bytes.
+ /// Type.
+ public object Deserialize(byte[] bytes, Type type)
+ {
+ return JsonSerializer.Deserialize(bytes, type, jsonSerializerOption);
+ }
+ ///
+ /// Deserializes the object.
+ ///
+ /// The object.
+ /// Value.
+ public object DeserializeObject(ArraySegment value)
+ {
+ var jr = new Utf8JsonReader(value);
+ jr.Read();
+ if (jr.TokenType == JsonTokenType.StartArray)
+ {
+ jr.Read();
+ var typeName = Encoding.UTF8.GetString(jr.ValueSpan.ToArray());
+ var type = Type.GetType(typeName, throwOnError: true);
+
+ jr.Read();
+ return JsonSerializer.Deserialize(ref jr, type, jsonSerializerOption);
+ }
+ else
+ {
+ throw new InvalidDataException("JsonTranscoder only supports [\"TypeName\", object]");
+ }
+ }
+ ///
+ //; Serialize the specified value.
+ ///
+ /// The serialize.
+ /// Value.
+ /// The 1st type parameter.
+ public byte[] Serialize(T value)
+ {
+ return JsonSerializer.SerializeToUtf8Bytes(value, jsonSerializerOption);
+ }
+ ///
+ /// Serializes the object.
+ ///
+ /// The object.
+ /// Object.
+ public ArraySegment SerializeObject(object obj)
+ {
+ var typeName = TypeHelper.BuildTypeName(obj.GetType());
+
+ using (var ms = new MemoryStream())
+ using (var jw = new Utf8JsonWriter(ms))
+ {
+ jw.WriteStartArray();
+ jw.WriteStringValue(typeName);
+
+ JsonSerializer.Serialize(jw, obj, jsonSerializerOption);
+
+ jw.WriteEndArray();
+
+ jw.Flush();
+
+ return new ArraySegment(ms.ToArray(), 0, (int)ms.Length);
+ }
+ }
+ }
+}
diff --git a/serialization/EasyCaching.Serialization.SystemTextJson/EasyCaching.Serialization.SystemTextJson.csproj b/serialization/EasyCaching.Serialization.SystemTextJson/EasyCaching.Serialization.SystemTextJson.csproj
new file mode 100644
index 00000000..9589b461
--- /dev/null
+++ b/serialization/EasyCaching.Serialization.SystemTextJson/EasyCaching.Serialization.SystemTextJson.csproj
@@ -0,0 +1,40 @@
+
+
+
+
+ netstandard2.0
+ EasyCaching Contributors
+ $(EasyCachingSTJsonPackageVersion)
+
+
+ A serialize library based on System.Text.Json
+
+ Caching,Serialization,Json
+ https://github.com/dotnetcore/EasyCaching
+ LICENSE
+ https://github.com/dotnetcore/EasyCaching
+ https://github.com/dotnetcore/EasyCaching
+ nuget-icon.png
+
+ $(EasyCachingSTJsonPackageNotes)
+
+
+
+
+ true
+ $(NoWarn);1591
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.Async.cs b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.Async.cs
index ed14392c..d833bbd3 100644
--- a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.Async.cs
+++ b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.Async.cs
@@ -74,7 +74,7 @@ public override async Task> BaseGetAsync(string cacheKey, Func<
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
var result = await _cache.GetAsync(cacheKey);
- if (result != null)
+ if (result != null || _options.CacheNulls)
{
CacheStats.OnHit();
@@ -99,7 +99,7 @@ public override async Task> BaseGetAsync(string cacheKey, Func<
}
var item = await dataRetriever();
- if (item != null)
+ if (item != null || _options.CacheNulls)
{
await SetAsync(cacheKey, item, expiration);
//remove mutex key
@@ -176,8 +176,8 @@ public override async Task> BaseGetAsync(string cacheKey)
return CacheValue.NoValue;
}
- }
-
+ }
+
///
/// Gets the count.
///
@@ -324,7 +324,7 @@ public override async Task BaseSetAllAsync(IDictionary value, Time
public override async Task BaseSetAsync(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
- ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
+ ArgumentCheck.NotNull(cacheValue, nameof(cacheValue), _options.CacheNulls);
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
if (MaxRdSecond > 0)
@@ -353,7 +353,7 @@ await _cache.SetAsync(
public override async Task BaseTrySetAsync(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
- ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
+ ArgumentCheck.NotNull(cacheValue, nameof(cacheValue), _options.CacheNulls);
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
if (MaxRdSecond > 0)
diff --git a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.Geo.cs b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.Geo.cs
index d7fc9c0e..45f1934d 100644
--- a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.Geo.cs
+++ b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.Geo.cs
@@ -13,11 +13,11 @@ public long GeoAdd(string cacheKey, List<(double longitude, double latitude, str
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNullAndCountGTZero(values, nameof(values));
- var list = new List<(double longitude, double latitude, object member)>();
+ var list = new List<(decimal longitude, decimal latitude, object member)>();
foreach (var item in values)
{
- list.Add((item.longitude, item.latitude, item.member));
+ list.Add(((decimal longitude, decimal latitude, object member))(item.longitude, item.latitude, item.member));
}
var res = _cache.GeoAdd(cacheKey, list.ToArray());
@@ -29,11 +29,11 @@ public async Task GeoAddAsync(string cacheKey, List<(double longitude, dou
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNullAndCountGTZero(values, nameof(values));
- var list = new List<(double longitude, double latitude, object member)>();
+ var list = new List<(decimal longitude, decimal latitude, object member)>();
foreach (var item in values)
{
- list.Add((item.longitude, item.latitude, item.member));
+ list.Add(((decimal longitude, decimal latitude, object member))(item.longitude, item.latitude, item.member));
}
var res = await _cache.GeoAddAsync(cacheKey, list.ToArray());
@@ -48,7 +48,7 @@ public async Task GeoAddAsync(string cacheKey, List<(double longitude, dou
ArgumentCheck.NotNullOrWhiteSpace(unit, nameof(unit));
var res = _cache.GeoDist(cacheKey, member1, member2, GetGeoUnit(unit));
- return res;
+ return (double?)res;
}
public async Task GeoDistAsync(string cacheKey, string member1, string member2, string unit = "m")
@@ -59,7 +59,7 @@ public async Task GeoAddAsync(string cacheKey, List<(double longitude, dou
ArgumentCheck.NotNullOrWhiteSpace(unit, nameof(unit));
var res = await _cache.GeoDistAsync(cacheKey, member1, member2, GetGeoUnit(unit));
- return res;
+ return (double?)res;
}
public List GeoHash(string cacheKey, List members)
@@ -92,7 +92,7 @@ public async Task> GeoHashAsync(string cacheKey, List membe
return res.ToList();
}
- public List<(double longitude, double latitude)?> GeoPos(string cacheKey, List members)
+ public List<(decimal longitude, decimal latitude)?> GeoPos(string cacheKey, List members)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNullAndCountGTZero(members, nameof(members));
@@ -107,7 +107,7 @@ public async Task> GeoHashAsync(string cacheKey, List membe
return res.ToList();
}
- public async Task> GeoPosAsync(string cacheKey, List members)
+ public async Task> GeoPosAsync(string cacheKey, List members)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNullAndCountGTZero(members, nameof(members));
diff --git a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.SortedSet.cs b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.SortedSet.cs
index 90d569f8..1c603ce3 100755
--- a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.SortedSet.cs
+++ b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.SortedSet.cs
@@ -11,11 +11,11 @@ public long ZAdd(string cacheKey, Dictionary cacheValues)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
- var param = new List<(double, object)>();
+ var param = new List<(decimal, object)>();
foreach (var item in cacheValues)
{
- param.Add((item.Value, _serializer.Serialize(item.Key)));
+ param.Add(((decimal, object))(item.Value, _serializer.Serialize(item.Key)));
}
var len = _cache.ZAdd(cacheKey, param.ToArray());
@@ -35,7 +35,7 @@ public long ZCount(string cacheKey, double min, double max)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
- var len = _cache.ZCount(cacheKey, min, max);
+ var len = _cache.ZCount(cacheKey, (decimal)min, (decimal)max);
return len;
}
public double ZIncrBy(string cacheKey, string field, double val = 1)
@@ -43,8 +43,8 @@ public double ZIncrBy(string cacheKey, string field, double val = 1)
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNullOrWhiteSpace(field, nameof(field));
- var value = _cache.ZIncrBy(cacheKey, field, val);
- return value;
+ var value = _cache.ZIncrBy(cacheKey, field, (decimal)val);
+ return (double)value;
}
public long ZLexCount(string cacheKey, string min, string max)
{
@@ -106,18 +106,18 @@ public long ZRem(string cacheKey, IList cacheValues)
var score = _cache.ZScore(cacheKey, bytes);
- return score;
+ return (double?)score;
}
public async Task ZAddAsync(string cacheKey, Dictionary cacheValues)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
- var param = new List<(double, object)>();
+ var param = new List<(decimal, object)>();
foreach (var item in cacheValues)
{
- param.Add((item.Value, _serializer.Serialize(item.Key)));
+ param.Add(((decimal, object))(item.Value, _serializer.Serialize(item.Key)));
}
var len = await _cache.ZAddAsync(cacheKey, param.ToArray());
@@ -138,7 +138,7 @@ public async Task ZCountAsync(string cacheKey, double min, double max)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
- var len = await _cache.ZCountAsync(cacheKey, min, max);
+ var len = await _cache.ZCountAsync(cacheKey, (decimal)min, (decimal)max);
return len;
}
@@ -147,8 +147,8 @@ public async Task ZIncrByAsync(string cacheKey, string field, double val
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNullOrWhiteSpace(field, nameof(field));
- var value= await _cache.ZIncrByAsync(cacheKey, field, val);
- return value;
+ var value= await _cache.ZIncrByAsync(cacheKey, field, (decimal)val);
+ return (double)value;
}
public async Task ZLexCountAsync(string cacheKey, string min, string max)
@@ -210,7 +210,7 @@ public async Task ZRemAsync(string cacheKey, IList cacheValues)
var score = await _cache.ZScoreAsync(cacheKey, bytes);
- return score;
+ return (double?)score;
}
}
diff --git a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.String.cs b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.String.cs
index ae298fdb..f87fbff4 100755
--- a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.String.cs
+++ b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.String.cs
@@ -26,16 +26,16 @@ public double IncrByFloat(string cacheKey, double value = 1)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
- var res = _cache.IncrByFloat(cacheKey, value);
- return res;
+ var res = _cache.IncrByFloat(cacheKey, (decimal)value);
+ return (double)res;
}
public async Task IncrByFloatAsync(string cacheKey, double value = 1)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
- var res = await _cache.IncrByFloatAsync(cacheKey, value);
- return res;
+ var res = await _cache.IncrByFloatAsync(cacheKey, (decimal)value);
+ return (double)res;
}
public bool StringSet(string cacheKey, string cacheValue, System.TimeSpan? expiration, string when)
diff --git a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.cs b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.cs
index 2c68fd59..f366f51b 100644
--- a/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.cs
+++ b/src/EasyCaching.CSRedis/DefaultCSRedisCachingProvider.cs
@@ -60,7 +60,7 @@ public DefaultCSRedisCachingProvider(
RedisOptions options,
ILoggerFactory loggerFactory = null)
{
- this._name = name;
+ this._name = name;
this._options = options;
this._logger = loggerFactory?.CreateLogger();
this._cache = clients.Single(x => x.Name.Equals(_name));
@@ -68,8 +68,8 @@ public DefaultCSRedisCachingProvider(
this._serializer = !string.IsNullOrWhiteSpace(options.SerializerName)
? serializers.Single(x => x.Name.Equals(options.SerializerName))
- : serializers.FirstOrDefault(x => x.Name.Equals(_name)) ?? serializers.Single(x => x.Name.Equals(EasyCachingConstValue.DefaultSerializerName));
-
+ : serializers.FirstOrDefault(x => x.Name.Equals(_name)) ?? serializers.Single(x => x.Name.Equals(EasyCachingConstValue.DefaultSerializerName));
+
this.ProviderName = this._name;
this.ProviderType = CachingProviderType.Redis;
this.ProviderStats = this._cacheStats;
@@ -87,7 +87,8 @@ public DefaultCSRedisCachingProvider(
ProviderType = ProviderType,
SerializerName = options.SerializerName,
SleepMs = options.SleepMs,
- Serializer = _serializer
+ Serializer = _serializer,
+ CacheNulls = options.CacheNulls,
};
}
@@ -101,8 +102,8 @@ public override bool BaseExists(string cacheKey)
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
return _cache.Exists(cacheKey);
- }
-
+ }
+
///
/// Flush this instance.
///
@@ -151,7 +152,7 @@ public override CacheValue BaseGet(string cacheKey, Func dataRetriever,
}
var item = dataRetriever();
- if (item != null)
+ if (item != null || _options.CacheNulls)
{
Set(cacheKey, item, expiration);
//remove mutex key
@@ -223,8 +224,8 @@ public override IDictionary> BaseGetAll(IEnumerable
/// Handles the prefix of CacheKey.
///
@@ -318,8 +319,8 @@ public override int BaseGetCount(string prefix = "")
}
return this.SearchRedisKeys(this.HandlePrefix(prefix)).Length;
- }
-
+ }
+
///
/// Remove the specified cacheKey.
///
@@ -376,7 +377,7 @@ public override void BaseRemoveByPrefix(string prefix)
public override void BaseSet(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
- ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
+ ArgumentCheck.NotNull(cacheValue, nameof(cacheValue), _options.CacheNulls);
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
if (MaxRdSecond > 0)
@@ -424,7 +425,7 @@ public override void BaseSetAll(IDictionary values, TimeSpan expir
public override bool BaseTrySet(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
- ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
+ ArgumentCheck.NotNull(cacheValue, nameof(cacheValue), _options.CacheNulls);
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
if (MaxRdSecond > 0)
diff --git a/src/EasyCaching.CSRedis/EasyCaching.CSRedis.csproj b/src/EasyCaching.CSRedis/EasyCaching.CSRedis.csproj
index 4d0230c0..bb0eedb6 100644
--- a/src/EasyCaching.CSRedis/EasyCaching.CSRedis.csproj
+++ b/src/EasyCaching.CSRedis/EasyCaching.CSRedis.csproj
@@ -32,7 +32,7 @@
-
+
diff --git a/src/EasyCaching.Core/Configurations/BaseProviderOptions.cs b/src/EasyCaching.Core/Configurations/BaseProviderOptions.cs
index 6937fda3..3ec88f96 100644
--- a/src/EasyCaching.Core/Configurations/BaseProviderOptions.cs
+++ b/src/EasyCaching.Core/Configurations/BaseProviderOptions.cs
@@ -40,5 +40,10 @@ public class BaseProviderOptions
/// Mainly for distributed cache
///
public string SerializerName { get; set; }
+
+ ///
+ /// Get or sets whether null values should be cached, default is false.
+ ///
+ public bool CacheNulls { get; set; } = false;
}
}
diff --git a/src/EasyCaching.Core/IRedisCachingProvider.cs b/src/EasyCaching.Core/IRedisCachingProvider.cs
index 5bdb9e18..c8183813 100644
--- a/src/EasyCaching.Core/IRedisCachingProvider.cs
+++ b/src/EasyCaching.Core/IRedisCachingProvider.cs
@@ -916,14 +916,14 @@ public interface IRedisCachingProvider
///
///
///
- List<(double longitude, double latitude)?> GeoPos(string cacheKey, List members);
+ List<(decimal longitude, decimal latitude)?> GeoPos(string cacheKey, List members);
///
/// https://redis.io/commands/geopos
///
///
///
///
- Task> GeoPosAsync(string cacheKey, List members);
+ Task> GeoPosAsync(string cacheKey, List members);
#endregion
object Eval(string script, string cacheKey, List