using System;
using System.Linq;
using EfDataAdapter.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace EfDataAdapter
{
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.UseEntityTypeConfiguration();
ApplyUtcDateTimeConverter(modelBuilder);
base.OnModelCreating(modelBuilder);
}
private static void ApplyUtcDateTimeConverter(ModelBuilder modelBuilder)
{
var dateTimeConverter = new ValueConverter<DateTime, DateTime>(v => v.ToUniversalTime(), v => DateTime.SpecifyKind(v, DateTimeKind.Utc));
var dateTimeNullableConverter = new ValueConverter<DateTime?, DateTime?>(v => v.HasValue ? v.Value.ToUniversalTime() : (DateTime?)null, v => v.HasValue ? DateTime.SpecifyKind(v.Value, DateTimeKind.Utc) : (DateTime?)null);
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTime));
foreach (var property in properties)
{
modelBuilder.Entity(entityType.Name).Property(property.Name)
.HasConversion(dateTimeConverter);
}
properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTime?));
foreach (var property in properties)
{
modelBuilder.Entity(entityType.Name).Property(property.Name)
.HasConversion(dateTimeNullableConverter);
}
}
}
}
}
///////////// Edit Api ModelBinding to ensure UTC by default
public class UtcDateTimeModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName)
.FirstValue;
// Geen waarde meegegeven
if (string.IsNullOrWhiteSpace(value))
{
bindingContext.Result = ModelBindingResult.Success(null);
return Task.CompletedTask;
}
if (DateTime.TryParse(value, out var date))
{
bindingContext.Result = ModelBindingResult.Success(DateTimeHelper.EnsureUtcDefaultUtc(date));
}
return Task.CompletedTask;
}
}
public class UtcDateTimeModelBinderProvider : IModelBinderProvider
{
public IModelBinder? GetBinder(ModelBinderProviderContext context)
{
var type = context.Metadata.ModelType;
if (type == typeof(DateTime) || type == typeof(DateTime?))
{
return new UtcDateTimeModelBinder();
}
return null;
}
}
/////////////
using Newtonsoft.Json.Serialization;
namespace WebApi
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(config =>
{
config.ModelBinderProviders.Insert(0, new UtcDateTimeModelBinderProvider());
})
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
});
}
}
}435300cookie-checkC# WebAPI Entity framework+ModelBinding+JSON UTC-time mapping