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>()
.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 Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Json.SystemTextJson.JsonConverters;
using Volo.Abp.Json.SystemTextJson.Modifiers;
namespace Volo.Abp.AspNetCore.Mvc.Json;
@ -26,6 +27,13 @@ public static class MvcCoreBuilderExtensions
options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(rootServiceProvider
.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;

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.ProxyScripting.Generators;
using Volo.Abp.Json;
using Volo.Abp.Timing;
namespace Volo.Abp.Http.Client.ClientProxying;
@ -33,9 +34,15 @@ public class ClientProxyRequestPayloadBuilder : ITransientDependency
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;
Clock = clock;
HttpClientProxyingOptions = httpClientProxyingOptions.Value;
}
@ -156,12 +163,12 @@ public class ClientProxyRequestPayloadBuilder : ITransientDependency
{
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
{
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);
}
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.ProxyScripting.Generators;
using Volo.Abp.Localization;
using Volo.Abp.Timing;
namespace Volo.Abp.Http.Client.ClientProxying;
@ -36,11 +37,16 @@ public class ClientProxyUrlBuilder : ITransientDependency
protected IServiceScopeFactory ServiceScopeFactory { 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;
HttpClientProxyingOptions = httpClientProxyingOptions.Value;
Clock = clock;
}
public async Task<string> GenerateUrlWithParametersAsync(ActionApiDescriptionModel action, IReadOnlyDictionary<string, object> methodArguments, ApiVersionInfo apiVersion)
@ -218,13 +224,18 @@ public class ClientProxyUrlBuilder : ITransientDependency
return true;
}
protected virtual Task<string?> ConvertValueToStringAsync(object? value)
protected virtual Task<string> ConvertValueToStringAsync(object value)
{
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 IClock _clock;
private readonly AbpJsonOptions _options;
private bool _skipDateTimeNormalization;
public AbpDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> options)
{
@ -26,6 +27,12 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
_options = options.Value;
}
public virtual AbpDateTimeConverter SkipDateTimeNormalization()
{
_skipDateTimeNormalization = true;
return this;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTime) || objectType == typeof(DateTime?);
@ -46,7 +53,7 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
if (reader.TokenType == JsonToken.Date)
{
return _clock.Normalize(reader.Value!.To<DateTime>());
return Normalize(reader.Value!.To<DateTime>());
}
if (reader.TokenType != JsonToken.String)
@ -67,20 +74,20 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
{
if (DateTime.TryParseExact(dateText, format, _culture, _dateTimeStyles, out var d1))
{
return _clock.Normalize(d1);
return Normalize(d1);
}
}
}
var date = DateTime.Parse(dateText!, _culture, _dateTimeStyles);
return _clock.Normalize(date);
return Normalize(date);
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value != null)
{
value = _clock.Normalize(value.To<DateTime>());
value = Normalize(value.To<DateTime>());
}
if (value is DateTime dateTime)
@ -111,4 +118,11 @@ public class AbpDateTimeConverter : DateTimeConverterBase, ITransientDependency
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>()
.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)
{
//Default contract resolver is AbpCamelCasePropertyNamesContractResolver}
settings.ContractResolver = new AbpDefaultContractResolver(RootServiceProvider.GetRequiredService<AbpDateTimeConverter>());
settings.ContractResolver = new AbpDefaultContractResolver(RootServiceProvider
.GetRequiredService<AbpDateTimeConverter>().SkipDateTimeNormalization());
}
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
.GetRequiredService<IOptions<AbpSystemTextJsonSerializerModifiersOptions>>());
});
context.Services.AddOptions<AbpSystemTextJsonSerializerModifiersOptions>()
.Configure<IServiceProvider>((options, rootServiceProvider) =>
{
options.Modifiers.Add(new AbpDateTimeConverterModifier(
rootServiceProvider.GetRequiredService<AbpDateTimeConverter>(),
rootServiceProvider.GetRequiredService<AbpNullableDateTimeConverter>()).CreateModifyAction());
var dateTimeConverter = rootServiceProvider.GetRequiredService<AbpDateTimeConverter>().SkipDateTimeNormalization();
var nullableDateTimeConverter = rootServiceProvider.GetRequiredService<AbpNullableDateTimeConverter>().SkipDateTimeNormalization();
options.JsonSerializerOptions.TypeInfoResolver.As<AbpDefaultJsonTypeInfoResolver>().Modifiers.Add(
new AbpDateTimeConverterModifier(dateTimeConverter, nullableDateTimeConverter)
.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 AbpJsonOptions _options;
private bool _skipDateTimeNormalization;
public AbpDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> abpJsonOptions)
{
@ -20,6 +21,12 @@ public class AbpDateTimeConverter : JsonConverter<DateTime>, ITransientDependenc
_options = abpJsonOptions.Value;
}
public virtual AbpDateTimeConverter SkipDateTimeNormalization()
{
_skipDateTimeNormalization = true;
return this;
}
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (_options.InputDateTimeFormats.Any())
@ -31,7 +38,7 @@ public class AbpDateTimeConverter : JsonConverter<DateTime>, ITransientDependenc
var s = reader.GetString();
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))
{
return _clock.Normalize(d3);
return Normalize(d3);
}
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))
{
return _clock.Normalize(d4);
return Normalize(d4);
}
}
@ -62,11 +69,16 @@ public class AbpDateTimeConverter : JsonConverter<DateTime>, ITransientDependenc
{
if (_options.OutputDateTimeFormat.IsNullOrWhiteSpace())
{
writer.WriteStringValue(_clock.Normalize(value));
writer.WriteStringValue(Normalize(value));
}
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 AbpJsonOptions _options;
private bool _skipDateTimeNormalization;
public AbpNullableDateTimeConverter(IClock clock, IOptions<AbpJsonOptions> abpJsonOptions)
{
@ -20,6 +21,12 @@ public class AbpNullableDateTimeConverter : JsonConverter<DateTime?>, ITransient
_options = abpJsonOptions.Value;
}
public virtual AbpNullableDateTimeConverter SkipDateTimeNormalization()
{
_skipDateTimeNormalization = true;
return this;
}
public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (_options.InputDateTimeFormats.Any())
@ -31,7 +38,7 @@ public class AbpNullableDateTimeConverter : JsonConverter<DateTime?>, ITransient
var s = reader.GetString();
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))
{
return _clock.Normalize(d2);
return Normalize(d2);
}
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))
{
return _clock.Normalize(d3);
return Normalize(d3);
}
}
@ -68,12 +75,17 @@ public class AbpNullableDateTimeConverter : JsonConverter<DateTime?>, ITransient
{
if (_options.OutputDateTimeFormat.IsNullOrWhiteSpace())
{
writer.WriteStringValue(_clock.Normalize(value.Value));
writer.WriteStringValue(Normalize(value.Value));
}
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);
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>
/// <returns>Converted DateTime</returns>
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