Browse Source

Use DateTimeModelBinder instead of SimpleTypeModelBinder for binding datetime.

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

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

@ -1,48 +1,56 @@
using System; using System;
using System.Globalization;
using System.Linq; using System.Linq;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.Timing; using Volo.Abp.Timing;
namespace Volo.Abp.AspNetCore.Mvc.ModelBinding namespace Volo.Abp.AspNetCore.Mvc.ModelBinding
{ {
public class AbpDateTimeModelBinderProvider : IModelBinderProvider public class AbpDateTimeModelBinderProvider : IModelBinderProvider
{ {
public IModelBinder GetBinder(ModelBinderProviderContext context) public IModelBinder GetBinder(ModelBinderProviderContext context)
{ {
if (context.Metadata.ModelType != typeof(DateTime) && var modelType = context.Metadata.UnderlyingOrModelType;
context.Metadata.ModelType != typeof(DateTime?)) if (modelType == typeof(DateTime))
{
return null;
}
if (context.Metadata.ContainerType == null)
{ {
if (context.Metadata is DefaultModelMetadata defaultModelMetadata && if (context.Metadata.ContainerType == null)
defaultModelMetadata.Attributes.Attributes.All(x => x.GetType() != typeof(DisableDateTimeNormalizationAttribute)))
{ {
return new AbpDateTimeModelBinder(context); if (context.Metadata is DefaultModelMetadata defaultModelMetadata &&
defaultModelMetadata.Attributes.Attributes.All(x => x.GetType() != typeof(DisableDateTimeNormalizationAttribute)))
{
return CreateAbpDateTimeModelBinder(context);
}
} }
} else
else {
{ var dateNormalizationDisabledForClass =
var dateNormalizationDisabledForClass = context.Metadata.ContainerType.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true);
context.Metadata.ContainerType.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true);
var dateNormalizationDisabledForProperty = context.Metadata.ContainerType var dateNormalizationDisabledForProperty = context.Metadata.ContainerType
.GetProperty(context.Metadata.PropertyName) .GetProperty(context.Metadata.PropertyName)
?.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true); ?.IsDefined(typeof(DisableDateTimeNormalizationAttribute), true);
if (!dateNormalizationDisabledForClass && if (!dateNormalizationDisabledForClass &&
dateNormalizationDisabledForProperty != null && dateNormalizationDisabledForProperty != null &&
!dateNormalizationDisabledForProperty.Value) !dateNormalizationDisabledForProperty.Value)
{ {
return new AbpDateTimeModelBinder(context); return CreateAbpDateTimeModelBinder(context);
}
} }
} }
return null; 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 dateTime1 = new DateTime(2020, 04, 19, 19, 05, 01);
var result = await _controller.GetWithDateTimeParameterAsync(dateTime1); var result = await _controller.GetWithDateTimeParameterAsync(dateTime1);
result.ShouldBe(dateTime1); result.ToUniversalTime().ShouldBe(dateTime1.ToUniversalTime());
} }
[Fact] [Fact]
@ -56,7 +56,7 @@ namespace Volo.Abp.Http.DynamicProxying
{ {
var dateTime1 = new DateTime(2020, 04, 19, 19, 05, 01); var dateTime1 = new DateTime(2020, 04, 19, 19, 05, 01);
var result = await _controller.GetWithDateTimeParameterAsync(dateTime1); var result = await _controller.GetWithDateTimeParameterAsync(dateTime1);
result.ShouldBe(dateTime1); result.ToUniversalTime().ShouldBe(dateTime1.ToUniversalTime());
} }
} }

Loading…
Cancel
Save