Browse Source

Merge pull request #8891 from abpframework/maliming/DateTimeModelBinder

Use DateTimeModelBinder instead of SimpleTypeModelBinder for binding datetime.
pull/9048/head
Halil İbrahim Kalkan 5 years ago
committed by GitHub
parent
commit
05522af6fd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinder.cs
  2. 56
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinderProvider.cs
  3. 4
      framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs

37
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinder.cs

@ -2,48 +2,29 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.Timing;
namespace Volo.Abp.AspNetCore.Mvc.ModelBinding
{
public class AbpDateTimeModelBinder : IModelBinder
{
private readonly Type _type;
private readonly SimpleTypeModelBinder _simpleTypeModelBinder;
private readonly DateTimeModelBinder _dateTimeModelBinder;
private readonly IClock _clock;
public AbpDateTimeModelBinder(ModelBinderProviderContext context)
public AbpDateTimeModelBinder(IClock clock, DateTimeModelBinder dateTimeModelBinder)
{
_type = context.Metadata.ModelType;
_clock = context.Services.GetRequiredService<IClock>();
_simpleTypeModelBinder = new SimpleTypeModelBinder(context.Metadata.ModelType,
context.Services.GetRequiredService<ILoggerFactory>());
_clock = clock;
_dateTimeModelBinder = dateTimeModelBinder;
}
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
await _simpleTypeModelBinder.BindModelAsync(bindingContext);
if (!bindingContext.Result.IsModelSet)
{
return;
}
if (_type == typeof(DateTime))
{
var dateTime = (DateTime) bindingContext.Result.Model;
bindingContext.Result = ModelBindingResult.Success(_clock.Normalize(dateTime));
}
else
await _dateTimeModelBinder.BindModelAsync(bindingContext);
if (bindingContext.Result.IsModelSet)
{
var dateTime = (DateTime?) bindingContext.Result.Model;
if (dateTime != null)
{
bindingContext.Result = ModelBindingResult.Success(_clock.Normalize(dateTime.Value));
}
// ReSharper disable once PossibleNullReferenceException
bindingContext.Result = ModelBindingResult.Success(_clock.Normalize((DateTime) bindingContext.Result.Model));
}
}
}
}
}

56
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ModelBinding/AbpDateTimeModelBinderProvider.cs

@ -1,48 +1,56 @@
using System;
using System.Globalization;
using System.Linq;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.Timing;
namespace Volo.Abp.AspNetCore.Mvc.ModelBinding
{
public class AbpDateTimeModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context.Metadata.ModelType != typeof(DateTime) &&
context.Metadata.ModelType != typeof(DateTime?))
{
return null;
}
if (context.Metadata.ContainerType == null)
var modelType = context.Metadata.UnderlyingOrModelType;
if (modelType == typeof(DateTime))
{
if (context.Metadata is DefaultModelMetadata defaultModelMetadata &&
defaultModelMetadata.Attributes.Attributes.All(x => x.GetType() != typeof(DisableDateTimeNormalizationAttribute)))
if (context.Metadata.ContainerType == null)
{
return new AbpDateTimeModelBinder(context);
if (context.Metadata is DefaultModelMetadata defaultModelMetadata &&
defaultModelMetadata.Attributes.Attributes.All(x => x.GetType() != typeof(DisableDateTimeNormalizationAttribute)))
{
return CreateAbpDateTimeModelBinder(context);
}
}
}
else
{
var dateNormalizationDisabledForClass =
context.Metadata.ContainerType.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true);
else
{
var dateNormalizationDisabledForClass =
context.Metadata.ContainerType.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true);
var dateNormalizationDisabledForProperty = context.Metadata.ContainerType
.GetProperty(context.Metadata.PropertyName)
?.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true);
var dateNormalizationDisabledForProperty = context.Metadata.ContainerType
.GetProperty(context.Metadata.PropertyName)
?.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true);
if (!dateNormalizationDisabledForClass &&
dateNormalizationDisabledForProperty != null &&
!dateNormalizationDisabledForProperty.Value)
{
return new AbpDateTimeModelBinder(context);
if (!dateNormalizationDisabledForClass &&
dateNormalizationDisabledForProperty != null &&
!dateNormalizationDisabledForProperty.Value)
{
return CreateAbpDateTimeModelBinder(context);
}
}
}
return null;
}
protected virtual AbpDateTimeModelBinder CreateAbpDateTimeModelBinder(ModelBinderProviderContext context)
{
const DateTimeStyles supportedStyles = DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AdjustToUniversal;
var dateTimeModelBinder = new DateTimeModelBinder(supportedStyles, context.Services.GetRequiredService<ILoggerFactory>());
return new AbpDateTimeModelBinder(context.Services.GetRequiredService<IClock>(), dateTimeModelBinder);
}
}
}

4
framework/test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs

@ -46,7 +46,7 @@ namespace Volo.Abp.Http.DynamicProxying
{
var dateTime1 = new DateTime(2020, 04, 19, 19, 05, 01);
var result = await _controller.GetWithDateTimeParameterAsync(dateTime1);
result.ShouldBe(dateTime1);
result.ToUniversalTime().ShouldBe(dateTime1.ToUniversalTime());
}
[Fact]
@ -56,7 +56,7 @@ namespace Volo.Abp.Http.DynamicProxying
{
var dateTime1 = new DateTime(2020, 04, 19, 19, 05, 01);
var result = await _controller.GetWithDateTimeParameterAsync(dateTime1);
result.ShouldBe(dateTime1);
result.ToUniversalTime().ShouldBe(dateTime1.ToUniversalTime());
}
}

Loading…
Cancel
Save