Open
Description
I have a model containing a DateTime property. When I am trying to fetch the saved property from memcached local timezone is added to the datetime value. How can I get exactly the same datetime value that I'm saving?
Response from the API
{
"original": {
"effectiveDate": "2020-06-29T16:45:18.235" // This is what I am saving in memcached
},
"fromCache": {
"effectiveDate": "2020-06-29T16:45:18.235+05:30" // When I fetch it from memcached, local timezone is added
},
"originalDate": "2020-06-29T16:45:18.235", // primitive datetime
"fromCacheDate": "2020-06-29T16:45:18.235", // fetched from cache, primitive datetime works fine
"jsonSerializerDesserialize": {
"EffectiveDate": "2020-06-29T16:45:18.235+05:30" // Using BsonDataWriter & JsonSerializer. This is used in DefaultTranscoder.cs
},
"jsonConvertDeserialize": {
"EffectiveDate": "2020-06-29T16:45:18.235" // using JsonConvert.Serialize works fine
}
}
WeatherForecastController.cs
using System;
using System.IO;
using System.Threading.Tasks;
using Enyim.Caching;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Bson;
namespace memcachedtester.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly IMemcachedClient _memcachedClient;
public WeatherForecastController(IMemcachedClient memcachedClient)
{
_memcachedClient = memcachedClient;
}
[HttpGet]
public async Task<dynamic> Get()
{
DateTime value = new DateTime(2020, 6, 29, 16, 45, 18, 235);
string key = "date";
DateTimeModel mappingRestrictionModel = new DateTimeModel
{
EffectiveDate = value
};
await _memcachedClient.SetAsync(key, mappingRestrictionModel, 120);
var r = await _memcachedClient.GetValueAsync<DateTimeModel>(key);
string key2 = "date2";
await _memcachedClient.SetAsync(key2, value, 120);
var r2 = await _memcachedClient.GetValueAsync<DateTime>(key2);
var q = this.SerializeObject(mappingRestrictionModel);
var w = this.DeserializeObject(q);
var q1 = JsonConvert.SerializeObject(mappingRestrictionModel);
var w1 = JsonConvert.DeserializeObject(q1);
var t = new TestClass
{
Original = mappingRestrictionModel,
FromCache = r,
OriginalDate = value,
FromCacheDate = r2,
JsonSerializerDesserialize = w,
JsonConvertDeserialize = w1,
};
return t;
}
protected virtual ArraySegment<byte> SerializeObject(object value)
{
using (var ms = new MemoryStream())
{
using (var writer = new BsonDataWriter(ms))
{
var serializer = new JsonSerializer();
serializer.Serialize(writer, value);
return new ArraySegment<byte>(ms.ToArray(), 0, (int)ms.Length);
}
}
}
protected virtual object DeserializeObject(ArraySegment<byte> value)
{
using (var ms = new MemoryStream(value.Array, value.Offset, value.Count))
{
using (var reader = new BsonDataReader(ms))
{
JsonSerializer serializer = new JsonSerializer();
return serializer.Deserialize(reader);
}
}
}
}
public class TestClass
{
public DateTimeModel Original { get; set; }
public DateTimeModel FromCache { get; set; }
public DateTime OriginalDate { get; set; }
public DateTime FromCacheDate { get; set; }
public object JsonSerializerDesserialize { get; set; }
public object JsonConvertDeserialize { get; set; }
}
public class DateTimeModel
{
public DateTime EffectiveDate { get; set; }
}
}
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json.Serialization;
namespace memcachedtester
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.AddEnyimMemcached();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEnyimMemcached();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
csproj file
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UserSecretsId>549e9dd1-7f33-4159-a6a5-19b7982528a8</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="EnyimMemcachedCore" Version="2.4.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.5" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.9.10" />
</ItemGroup>
</Project>
Activity
IcoDeveloper commentedon Dec 16, 2023
That's an issue with the jsonserializer. you need to set an option to keep it from fiddling with timestamps.