Browse Source

Implement timezone override in middleware from request sources and add unit tests

pull/22236/head
maliming 2 years ago
parent
commit
f3f14a8dd9
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 35
      framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Timing/AbpTimeZoneMiddleware.cs
  2. 6
      framework/src/Volo.Abp.Timing/Volo/Abp/Timing/TimeZoneConsts.cs
  3. 1
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs
  4. 64
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Timing/AbpTimeZoneMiddleware_Tests.cs
  5. 27
      framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Timing/TimingTestController.cs

35
framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Timing/AbpTimeZoneMiddleware.cs

@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
@ -13,8 +14,14 @@ public class AbpTimeZoneMiddleware : AbpMiddlewareBase, ITransientDependency
{
public async override Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var settingProvider = context.RequestServices.GetRequiredService<ISettingProvider>();
var timezone = await settingProvider.GetOrNullAsync(TimingSettingNames.TimeZone);
var timezone = await GetTimezoneFromRequestAsync(context);
if (timezone.IsNullOrWhiteSpace())
{
var settingProvider = context.RequestServices.GetRequiredService<ISettingProvider>();
timezone = await settingProvider.GetOrNullAsync(TimingSettingNames.TimeZone);
}
if (timezone.IsNullOrEmpty())
{
await next(context);
@ -27,4 +34,28 @@ public class AbpTimeZoneMiddleware : AbpMiddlewareBase, ITransientDependency
await next(context);
}
}
protected virtual async Task<string? > GetTimezoneFromRequestAsync(HttpContext context)
{
var timeZoneSources = new Func<HttpContext, Task<string?>>[]
{
ctx => Task.FromResult(ctx.Request.Headers[TimeZoneConsts.DefaultTimeZoneKey].FirstOrDefault()),
ctx => Task.FromResult<string?>(ctx.Request.Query[TimeZoneConsts.DefaultTimeZoneKey].ToString()),
async ctx => ctx.Request.HasFormContentType
? (await ctx.Request.ReadFormAsync())[TimeZoneConsts.DefaultTimeZoneKey].ToString()
: null,
ctx => Task.FromResult(ctx.Request.Cookies[TimeZoneConsts.DefaultTimeZoneKey]?.ToString()),
};
foreach (var source in timeZoneSources)
{
var timezone = await source(context);
if (!string.IsNullOrEmpty(timezone))
{
return timezone;
}
}
return null;
}
}

6
framework/src/Volo.Abp.Timing/Volo/Abp/Timing/TimeZoneConsts.cs

@ -0,0 +1,6 @@
namespace Volo.Abp.Timing;
public class TimeZoneConsts
{
public const string DefaultTimeZoneKey = "__timezone";
}

1
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/AbpAspNetCoreMvcTestModule.cs

@ -159,6 +159,7 @@ public class AbpAspNetCoreMvcTestModule : AbpModule
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseAbpTimeZone();
app.UseAuditing();
app.UseUnitOfWork();
app.UseConfiguredEndpoints();

64
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Timing/AbpTimeZoneMiddleware_Tests.cs

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Testing;
using Shouldly;
using Volo.Abp.Timing;
using Xunit;
namespace Volo.Abp.AspNetCore.Mvc.Timing;
public class AbpTimeZoneMiddleware_Tests : AspNetCoreMvcTestBase
{
private readonly ICurrentTimezoneProvider _currentTimezoneProvider;
public AbpTimeZoneMiddleware_Tests()
{
_currentTimezoneProvider = GetRequiredService<ICurrentTimezoneProvider>();
}
[Fact]
public async Task Should_Override_TimeZone_Setting_By_Request()
{
using (_currentTimezoneProvider.Change("UTC"))
{
var result = await Client.GetStringAsync("api/timing-test");
result.ShouldBe("UTC");
}
// Query string
using (_currentTimezoneProvider.Change("UTC"))
{
var result = await Client.GetStringAsync("api/timing-test?__timezone=Europe/Istanbul");
result.ShouldBe("Europe/Istanbul");
}
// Header
using (_currentTimezoneProvider.Change("UTC"))
{
Client.DefaultRequestHeaders.Add("__timezone", "Asia/Shanghai");
var result = await Client.GetStringAsync("api/timing-test");
result.ShouldBe("Asia/Shanghai");
}
// Form
using (_currentTimezoneProvider.Change("UTC"))
{
Client.DefaultRequestHeaders.Remove("__timezone");
var result = await Client.PostAsync("api/timing-test", new FormUrlEncodedContent(new[] {new KeyValuePair<string, string>("__timezone", "Europe/Germany")}));
(await result.Content.ReadAsStringAsync()).ShouldBe("Europe/Germany");
}
// Cookie
using (_currentTimezoneProvider.Change("UTC"))
{
Client.DefaultRequestHeaders.Remove("__timezone");
Client.DefaultRequestHeaders.Add("Cookie", "__timezone=Europe/Istanbul");
var result = await Client.GetStringAsync("api/timing-test");
result.ShouldBe("Europe/Istanbul");
}
}
}

27
framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Timing/TimingTestController.cs

@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Timing;
namespace Volo.Abp.AspNetCore.Mvc.Timing;
[Route("api/timing-test")]
public class UnitOfWorkTestController : AbpController
{
private readonly ICurrentTimezoneProvider _currentTimezoneProvider;
public UnitOfWorkTestController(ICurrentTimezoneProvider currentTimezoneProvider)
{
_currentTimezoneProvider = currentTimezoneProvider;
}
[HttpGet]
public ActionResult GetAsync()
{
return Content(_currentTimezoneProvider.TimeZone ?? "null");
}
[HttpPost]
public ActionResult PostAsync()
{
return Content(_currentTimezoneProvider.TimeZone ?? "null");
}
}
Loading…
Cancel
Save