Browse Source

Add DateTimeOffset conversion method to IClock and only normalizing DateTime in MVC.

pull/22236/head
maliming 2 years ago
parent
commit
5e3fff446e
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs
  2. 8
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs
  3. 28
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyRequestPayloadBuilder.cs
  4. 21
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyUrlBuilder.cs
  5. 22
      framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDateTimeConverter.cs
  6. 3
      framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs
  7. 3
      framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs
  8. 13
      framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs
  9. 22
      framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs
  10. 22
      framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs
  11. 12
      framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Clock.cs
  12. 7
      framework/src/Volo.Abp.Timing/Volo/Abp/Timing/IClock.cs
  13. 26
      framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonNewtonsoftTestModule.cs
  14. 0
      framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestBase.cs
  15. 53
      framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestModule.cs

4
framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs

@ -16,7 +16,9 @@ public class AbpAspNetCoreMvcNewtonsoftModule : AbpModule
context.Services.AddOptions<MvcNewtonsoftJsonOptions>() context.Services.AddOptions<MvcNewtonsoftJsonOptions>()
.Configure<IServiceProvider>((options, rootServiceProvider) => .Configure<IServiceProvider>((options, rootServiceProvider) =>
{ {
options.SerializerSettings.ContractResolver = new AbpCamelCasePropertyNamesContractResolver(rootServiceProvider.GetRequiredService<AbpDateTimeConverter>()); options.SerializerSettings.ContractResolver =
new AbpCamelCasePropertyNamesContractResolver(rootServiceProvider
.GetRequiredService<AbpDateTimeConverter>());
}); });
} }
} }

8
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs

@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Json.SystemTextJson.JsonConverters; using Volo.Abp.Json.SystemTextJson.JsonConverters;
using Volo.Abp.Json.SystemTextJson.Modifiers;
namespace Volo.Abp.AspNetCore.Mvc.Json; namespace Volo.Abp.AspNetCore.Mvc.Json;
@ -26,6 +27,13 @@ public static class MvcCoreBuilderExtensions
options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(rootServiceProvider options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(rootServiceProvider
.GetRequiredService<IOptions<AbpSystemTextJsonSerializerModifiersOptions>>()); .GetRequiredService<IOptions<AbpSystemTextJsonSerializerModifiersOptions>>());
var dateTimeConverter = rootServiceProvider.GetRequiredService<AbpDateTimeConverter>();
var nullableDateTimeConverter = rootServiceProvider.GetRequiredService<AbpNullableDateTimeConverter>();
options.JsonSerializerOptions.TypeInfoResolver.As<AbpDefaultJsonTypeInfoResolver>().Modifiers.Add(
new AbpDateTimeConverterModifier(dateTimeConverter, nullableDateTimeConverter)
.CreateModifyAction());
}); });
return builder; return builder;

28
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyRequestPayloadBuilder.cs

@ -15,6 +15,7 @@ using Volo.Abp.Http.Client.Proxying;
using Volo.Abp.Http.Modeling; using Volo.Abp.Http.Modeling;
using Volo.Abp.Http.ProxyScripting.Generators; using Volo.Abp.Http.ProxyScripting.Generators;
using Volo.Abp.Json; using Volo.Abp.Json;
using Volo.Abp.Timing;
namespace Volo.Abp.Http.Client.ClientProxying; namespace Volo.Abp.Http.Client.ClientProxying;
@ -33,9 +34,15 @@ public class ClientProxyRequestPayloadBuilder : ITransientDependency
protected AbpHttpClientProxyingOptions HttpClientProxyingOptions { get; } protected AbpHttpClientProxyingOptions HttpClientProxyingOptions { get; }
public ClientProxyRequestPayloadBuilder(IServiceScopeFactory serviceScopeFactory, IOptions<AbpHttpClientProxyingOptions> httpClientProxyingOptions) protected IClock Clock { get; }
public ClientProxyRequestPayloadBuilder(
IServiceScopeFactory serviceScopeFactory,
IOptions<AbpHttpClientProxyingOptions> httpClientProxyingOptions,
IClock clock)
{ {
ServiceScopeFactory = serviceScopeFactory; ServiceScopeFactory = serviceScopeFactory;
Clock = clock;
HttpClientProxyingOptions = httpClientProxyingOptions.Value; HttpClientProxyingOptions = httpClientProxyingOptions.Value;
} }
@ -156,12 +163,12 @@ public class ClientProxyRequestPayloadBuilder : ITransientDependency
{ {
foreach (var item in (IEnumerable) value) foreach (var item in (IEnumerable) value)
{ {
formData.Add(new StringContent(item.ToString()!, Encoding.UTF8), parameter.Name); formData.Add(new StringContent(await ConvertValueToStringAsync(item), Encoding.UTF8), parameter.Name);
} }
} }
else else
{ {
formData.Add(new StringContent(value.ToString()!, Encoding.UTF8), parameter.Name); formData.Add(new StringContent(await ConvertValueToStringAsync(value), Encoding.UTF8), parameter.Name);
} }
} }
@ -172,4 +179,19 @@ public class ClientProxyRequestPayloadBuilder : ITransientDependency
{ {
return await converter.ConvertAsync(actionApiDescription, parameterApiDescription, value); return await converter.ConvertAsync(actionApiDescription, parameterApiDescription, value);
} }
protected virtual Task<string> ConvertValueToStringAsync(object value)
{
if (value is DateTime dateTimeValue)
{
if (Clock.SupportsMultipleTimezone || dateTimeValue.Kind == DateTimeKind.Utc)
{
return Task.FromResult(dateTimeValue.ToUniversalTime().ToString("O"));
}
return Task.FromResult(dateTimeValue.ToString("yyyy-MM-ddTHH:mm:ss.fffffff").TrimEnd('0').TrimEnd('.'));
}
return Task.FromResult(value.ToString()!);
}
} }

21
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/ClientProxying/ClientProxyUrlBuilder.cs

@ -14,6 +14,7 @@ using Volo.Abp.Http.Client.Proxying;
using Volo.Abp.Http.Modeling; using Volo.Abp.Http.Modeling;
using Volo.Abp.Http.ProxyScripting.Generators; using Volo.Abp.Http.ProxyScripting.Generators;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Timing;
namespace Volo.Abp.Http.Client.ClientProxying; namespace Volo.Abp.Http.Client.ClientProxying;
@ -36,11 +37,16 @@ public class ClientProxyUrlBuilder : ITransientDependency
protected IServiceScopeFactory ServiceScopeFactory { get; } protected IServiceScopeFactory ServiceScopeFactory { get; }
protected AbpHttpClientProxyingOptions HttpClientProxyingOptions { get; } protected AbpHttpClientProxyingOptions HttpClientProxyingOptions { get; }
protected IClock Clock { get; }
public ClientProxyUrlBuilder(IServiceScopeFactory serviceScopeFactory, IOptions<AbpHttpClientProxyingOptions> httpClientProxyingOptions) public ClientProxyUrlBuilder(
IServiceScopeFactory serviceScopeFactory,
IOptions<AbpHttpClientProxyingOptions> httpClientProxyingOptions,
IClock clock)
{ {
ServiceScopeFactory = serviceScopeFactory; ServiceScopeFactory = serviceScopeFactory;
HttpClientProxyingOptions = httpClientProxyingOptions.Value; HttpClientProxyingOptions = httpClientProxyingOptions.Value;
Clock = clock;
} }
public async Task<string> GenerateUrlWithParametersAsync(ActionApiDescriptionModel action, IReadOnlyDictionary<string, object> methodArguments, ApiVersionInfo apiVersion) public async Task<string> GenerateUrlWithParametersAsync(ActionApiDescriptionModel action, IReadOnlyDictionary<string, object> methodArguments, ApiVersionInfo apiVersion)
@ -218,13 +224,18 @@ public class ClientProxyUrlBuilder : ITransientDependency
return true; return true;
} }
protected virtual Task<string?> ConvertValueToStringAsync(object? value) protected virtual Task<string> ConvertValueToStringAsync(object value)
{ {
if (value is DateTime dateTimeValue) if (value is DateTime dateTimeValue)
{ {
return Task.FromResult(dateTimeValue.ToUniversalTime().ToString("O"))!; if (Clock.SupportsMultipleTimezone || dateTimeValue.Kind == DateTimeKind.Utc)
{
return Task.FromResult(dateTimeValue.ToUniversalTime().ToString("O"));
}
return Task.FromResult(dateTimeValue.ToString("yyyy-MM-ddTHH:mm:ss.fffffff").TrimEnd('0').TrimEnd('.'));
} }
return Task.FromResult(value?.ToString()); return Task.FromResult(value.ToString()!);
} }
} }

22
framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDateTimeConverter.cs

@ -19,6 +19,7 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
private readonly CultureInfo _culture = CultureInfo.InvariantCulture; private readonly CultureInfo _culture = CultureInfo.InvariantCulture;
private readonly IClock _clock; private readonly IClock _clock;
private readonly AbpJsonOptions _options; private readonly AbpJsonOptions _options;
private bool _skipDateTimeNormalization;
public AbpDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> options) public AbpDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> options)
{ {
@ -26,6 +27,12 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
_options = options.Value; _options = options.Value;
} }
public virtual AbpDateTimeConverter SkipDateTimeNormalization()
{
_skipDateTimeNormalization = true;
return this;
}
public override bool CanConvert(Type objectType) public override bool CanConvert(Type objectType)
{ {
return objectType == typeof(DateTime) || objectType == typeof(DateTime?); return objectType == typeof(DateTime) || objectType == typeof(DateTime?);
@ -46,7 +53,7 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
if (reader.TokenType == JsonToken.Date) if (reader.TokenType == JsonToken.Date)
{ {
return _clock.Normalize(reader.Value!.To<DateTime>()); return Normalize(reader.Value!.To<DateTime>());
} }
if (reader.TokenType != JsonToken.String) if (reader.TokenType != JsonToken.String)
@ -67,20 +74,20 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
{ {
if (DateTime.TryParseExact(dateText, format, _culture, _dateTimeStyles, out var d1)) if (DateTime.TryParseExact(dateText, format, _culture, _dateTimeStyles, out var d1))
{ {
return _clock.Normalize(d1); return Normalize(d1);
} }
} }
} }
var date = DateTime.Parse(dateText!, _culture, _dateTimeStyles); var date = DateTime.Parse(dateText!, _culture, _dateTimeStyles);
return _clock.Normalize(date); return Normalize(date);
} }
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{ {
if (value != null) if (value != null)
{ {
value = _clock.Normalize(value.To<DateTime>()); value = Normalize(value.To<DateTime>());
} }
if (value is DateTime dateTime) if (value is DateTime dateTime)
@ -111,4 +118,11 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
return ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableDateTimeNormalizationAttribute>(member) == null; return ReflectionHelper.GetSingleAttributeOfMemberOrDeclaringTypeOrDefault<DisableDateTimeNormalizationAttribute>(member) == null;
} }
protected virtual DateTime Normalize(DateTime dateTime)
{
return _skipDateTimeNormalization
? dateTime
: _clock.Normalize(dateTime);
}
} }

3
framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs

@ -13,7 +13,8 @@ public class AbpJsonNewtonsoftModule : AbpModule
context.Services.AddOptions<AbpNewtonsoftJsonSerializerOptions>() context.Services.AddOptions<AbpNewtonsoftJsonSerializerOptions>()
.Configure<IServiceProvider>((options, rootServiceProvider) => .Configure<IServiceProvider>((options, rootServiceProvider) =>
{ {
options.JsonSerializerSettings.ContractResolver = new AbpCamelCasePropertyNamesContractResolver(rootServiceProvider.GetRequiredService<AbpDateTimeConverter>()); options.JsonSerializerSettings.ContractResolver = new AbpCamelCasePropertyNamesContractResolver(
rootServiceProvider.GetRequiredService<AbpDateTimeConverter>().SkipDateTimeNormalization());
}); });
} }
} }

3
framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs

@ -86,7 +86,8 @@ public class AbpNewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency
if (!camelCase) if (!camelCase)
{ {
//Default contract resolver is AbpCamelCasePropertyNamesContractResolver} //Default contract resolver is AbpCamelCasePropertyNamesContractResolver}
settings.ContractResolver = new AbpDefaultContractResolver(RootServiceProvider.GetRequiredService<AbpDateTimeConverter>()); settings.ContractResolver = new AbpDefaultContractResolver(RootServiceProvider
.GetRequiredService<AbpDateTimeConverter>().SkipDateTimeNormalization());
} }
if (indented) if (indented)

13
framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs

@ -29,14 +29,13 @@ public class AbpJsonSystemTextJsonModule : AbpModule
options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(rootServiceProvider options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(rootServiceProvider
.GetRequiredService<IOptions<AbpSystemTextJsonSerializerModifiersOptions>>()); .GetRequiredService<IOptions<AbpSystemTextJsonSerializerModifiersOptions>>());
});
context.Services.AddOptions<AbpSystemTextJsonSerializerModifiersOptions>() var dateTimeConverter = rootServiceProvider.GetRequiredService<AbpDateTimeConverter>().SkipDateTimeNormalization();
.Configure<IServiceProvider>((options, rootServiceProvider) => var nullableDateTimeConverter = rootServiceProvider.GetRequiredService<AbpNullableDateTimeConverter>().SkipDateTimeNormalization();
{
options.Modifiers.Add(new AbpDateTimeConverterModifier( options.JsonSerializerOptions.TypeInfoResolver.As<AbpDefaultJsonTypeInfoResolver>().Modifiers.Add(
rootServiceProvider.GetRequiredService<AbpDateTimeConverter>(), new AbpDateTimeConverterModifier(dateTimeConverter, nullableDateTimeConverter)
rootServiceProvider.GetRequiredService<AbpNullableDateTimeConverter>()).CreateModifyAction()); .CreateModifyAction());
}); });
} }
} }

22
framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpDateTimeConverter.cs

@ -13,6 +13,7 @@ public class AbpDateTimeConverter : JsonConverter<DateTime>, ITransientDependenc
{ {
private readonly IClock _clock; private readonly IClock _clock;
private readonly AbpJsonOptions _options; private readonly AbpJsonOptions _options;
private bool _skipDateTimeNormalization;
public AbpDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> abpJsonOptions) public AbpDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> abpJsonOptions)
{ {
@ -20,6 +21,12 @@ public class AbpDateTimeConverter : JsonConverter<DateTime>, ITransientDependenc
_options = abpJsonOptions.Value; _options = abpJsonOptions.Value;
} }
public virtual AbpDateTimeConverter SkipDateTimeNormalization()
{
_skipDateTimeNormalization = true;
return this;
}
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{ {
if (_options.InputDateTimeFormats.Any()) if (_options.InputDateTimeFormats.Any())
@ -31,7 +38,7 @@ public class AbpDateTimeConverter : JsonConverter<DateTime>, ITransientDependenc
var s = reader.GetString(); var s = reader.GetString();
if (DateTime.TryParseExact(s, format, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d1)) if (DateTime.TryParseExact(s, format, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d1))
{ {
return _clock.Normalize(d1); return Normalize(d1);
} }
} }
} }
@ -43,7 +50,7 @@ public class AbpDateTimeConverter : JsonConverter<DateTime>, ITransientDependenc
if (reader.TryGetDateTime(out var d3)) if (reader.TryGetDateTime(out var d3))
{ {
return _clock.Normalize(d3); return Normalize(d3);
} }
var dateText = reader.GetString(); var dateText = reader.GetString();
@ -51,7 +58,7 @@ public class AbpDateTimeConverter : JsonConverter<DateTime>, ITransientDependenc
{ {
if (DateTime.TryParse(dateText, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d4)) if (DateTime.TryParse(dateText, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d4))
{ {
return _clock.Normalize(d4); return Normalize(d4);
} }
} }
@ -62,11 +69,16 @@ public class AbpDateTimeConverter : JsonConverter<DateTime>, ITransientDependenc
{ {
if (_options.OutputDateTimeFormat.IsNullOrWhiteSpace()) if (_options.OutputDateTimeFormat.IsNullOrWhiteSpace())
{ {
writer.WriteStringValue(_clock.Normalize(value)); writer.WriteStringValue(Normalize(value));
} }
else else
{ {
writer.WriteStringValue(_clock.Normalize(value).ToString(_options.OutputDateTimeFormat, CultureInfo.CurrentUICulture)); writer.WriteStringValue(Normalize(value).ToString(_options.OutputDateTimeFormat, CultureInfo.CurrentUICulture));
} }
} }
protected virtual DateTime Normalize(DateTime dateTime)
{
return _skipDateTimeNormalization ? dateTime : _clock.Normalize(dateTime);
}
} }

22
framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/JsonConverters/AbpNullableDateTimeConverter.cs

@ -13,6 +13,7 @@ public class AbpNullableDateTimeConverter : JsonConverter<DateTime?>, ITransient
{ {
private readonly IClock _clock; private readonly IClock _clock;
private readonly AbpJsonOptions _options; private readonly AbpJsonOptions _options;
private bool _skipDateTimeNormalization;
public AbpNullableDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> abpJsonOptions) public AbpNullableDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> abpJsonOptions)
{ {
@ -20,6 +21,12 @@ public class AbpNullableDateTimeConverter : JsonConverter<DateTime?>, ITransient
_options = abpJsonOptions.Value; _options = abpJsonOptions.Value;
} }
public virtual AbpNullableDateTimeConverter SkipDateTimeNormalization()
{
_skipDateTimeNormalization = true;
return this;
}
public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{ {
if (_options.InputDateTimeFormats.Any()) if (_options.InputDateTimeFormats.Any())
@ -31,7 +38,7 @@ public class AbpNullableDateTimeConverter : JsonConverter<DateTime?>, ITransient
var s = reader.GetString(); var s = reader.GetString();
if (DateTime.TryParseExact(s, format, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d1)) if (DateTime.TryParseExact(s, format, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d1))
{ {
return _clock.Normalize(d1); return Normalize(d1);
} }
} }
} }
@ -43,7 +50,7 @@ public class AbpNullableDateTimeConverter : JsonConverter<DateTime?>, ITransient
if (reader.TryGetDateTime(out var d2)) if (reader.TryGetDateTime(out var d2))
{ {
return _clock.Normalize(d2); return Normalize(d2);
} }
var dateText = reader.GetString(); var dateText = reader.GetString();
@ -51,7 +58,7 @@ public class AbpNullableDateTimeConverter : JsonConverter<DateTime?>, ITransient
{ {
if (DateTime.TryParse(dateText, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d3)) if (DateTime.TryParse(dateText, CultureInfo.CurrentUICulture, DateTimeStyles.None, out var d3))
{ {
return _clock.Normalize(d3); return Normalize(d3);
} }
} }
@ -68,12 +75,17 @@ public class AbpNullableDateTimeConverter : JsonConverter<DateTime?>, ITransient
{ {
if (_options.OutputDateTimeFormat.IsNullOrWhiteSpace()) if (_options.OutputDateTimeFormat.IsNullOrWhiteSpace())
{ {
writer.WriteStringValue(_clock.Normalize(value.Value)); writer.WriteStringValue(Normalize(value.Value));
} }
else else
{ {
writer.WriteStringValue(_clock.Normalize(value.Value).ToString(_options.OutputDateTimeFormat, CultureInfo.CurrentUICulture)); writer.WriteStringValue(Normalize(value.Value).ToString(_options.OutputDateTimeFormat, CultureInfo.CurrentUICulture));
} }
} }
} }
protected virtual DateTime Normalize(DateTime dateTime)
{
return _skipDateTimeNormalization ? dateTime : _clock.Normalize(dateTime);
}
} }

12
framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Clock.cs

@ -58,4 +58,16 @@ public class Clock : IClock, ITransientDependency
var timezoneInfo = TimezoneProvider.GetTimeZoneInfo(CurrentTimezoneProvider.TimeZone); var timezoneInfo = TimezoneProvider.GetTimeZoneInfo(CurrentTimezoneProvider.TimeZone);
return TimeZoneInfo.ConvertTime(dateTime, timezoneInfo); return TimeZoneInfo.ConvertTime(dateTime, timezoneInfo);
} }
public virtual DateTimeOffset Convert(DateTimeOffset dateTimeOffset)
{
if (!SupportsMultipleTimezone ||
CurrentTimezoneProvider.TimeZone.IsNullOrWhiteSpace())
{
return dateTimeOffset;
}
var timezoneInfo = TimezoneProvider.GetTimeZoneInfo(CurrentTimezoneProvider.TimeZone);
return TimeZoneInfo.ConvertTime(dateTimeOffset, timezoneInfo);
}
} }

7
framework/src/Volo.Abp.Timing/Volo/Abp/Timing/IClock.cs

@ -32,4 +32,11 @@ public interface IClock
/// <param name="dateTime">DateTime to be normalized.</param> /// <param name="dateTime">DateTime to be normalized.</param>
/// <returns>Converted DateTime</returns> /// <returns>Converted DateTime</returns>
DateTime Convert(DateTime dateTime); DateTime Convert(DateTime dateTime);
/// <summary>
/// Converts given <see cref="DateTimeOffset"/> to user's time zone.
/// </summary>
/// <param name="dateTimeOffset">DateTimeOffset to be normalized.</param>
/// <returns>Converted DateTimeOffset</returns>
DateTimeOffset Convert(DateTimeOffset dateTimeOffset);
} }

26
framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonNewtonsoftTestModule.cs

@ -1,26 +0,0 @@
using Volo.Abp.Autofac;
using Volo.Abp.Json.Newtonsoft;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Modularity;
namespace Volo.Abp.Json;
[DependsOn(
typeof(AbpAutofacModule),
typeof(AbpJsonSystemTextJsonModule),
typeof(AbpTestBaseModule)
)]
public class AbpJsonSystemTextJsonTestModule : AbpModule
{
}
[DependsOn(
typeof(AbpAutofacModule),
typeof(AbpJsonNewtonsoftModule),
typeof(AbpTestBaseModule)
)]
public class AbpJsonNewtonsoftTestModule : AbpModule
{
}

0
framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonSystemTextJsonTestBase.cs → framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestBase.cs

53
framework/test/Volo.Abp.Json.Tests/Volo/Abp/Json/AbpJsonTestModule.cs

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Autofac;
using Volo.Abp.Json.Newtonsoft;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Json.SystemTextJson.JsonConverters;
using Volo.Abp.Json.SystemTextJson.Modifiers;
using Volo.Abp.Modularity;
namespace Volo.Abp.Json;
[DependsOn(
typeof(AbpAutofacModule),
typeof(AbpJsonSystemTextJsonModule),
typeof(AbpTestBaseModule)
)]
public class AbpJsonSystemTextJsonTestModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddOptions<AbpSystemTextJsonSerializerOptions>()
.Configure<IServiceProvider>((options, rootServiceProvider) =>
{
if (options.JsonSerializerOptions.TypeInfoResolver != null)
{
var modifiers = options.JsonSerializerOptions.TypeInfoResolver.As<AbpDefaultJsonTypeInfoResolver>().Modifiers;
modifiers.RemoveAll(x => x.Target?.GetType() == typeof(AbpDateTimeConverterModifier));
modifiers.Add(new AbpDateTimeConverterModifier(
rootServiceProvider.GetRequiredService<SystemTextJson.JsonConverters.AbpDateTimeConverter>(),
rootServiceProvider.GetRequiredService<AbpNullableDateTimeConverter>()).CreateModifyAction());
}
});
}
}
[DependsOn(
typeof(AbpAutofacModule),
typeof(AbpJsonNewtonsoftModule),
typeof(AbpTestBaseModule)
)]
public class AbpJsonNewtonsoftTestModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddOptions<AbpNewtonsoftJsonSerializerOptions>()
.Configure<IServiceProvider>((options, rootServiceProvider) =>
{
options.JsonSerializerSettings.ContractResolver = new AbpCamelCasePropertyNamesContractResolver(
rootServiceProvider.GetRequiredService<Newtonsoft.AbpDateTimeConverter>());
});
}
}
Loading…
Cancel
Save