在调用 API 之前将所有内容转换为特定日期时区

Convert Everything to A Specific Date Timezone before calling an API

我们正在寻求将所有内容转换为 DateTimeZone 太平洋标准时间。

  1. 数据库团队没有利用 sql datetimeoffset
  2. Web 团队本可以使用 Moment.Js Angular 应用程序设置将日期设置为太平洋标准时区,但现在使用的是日期。

其中有很多已经来不及更改,跨数据库、1000 多个表和应用程序代码。

我被要求解决这个问题,因此数据库中存储的任何日期在每个 API 之前都转换为 PST。

我创建了名为 DateTimeExtensions.ToPacificTimeZone(newDateTime) 的静态函数。

1)我们创建了方法ObjectDateTimeConverter,它遍历了所有class个DTO成员,嵌套了classes, 它找到 Any Datetime class 成员,并运行 PacificTimeZone 静态函数。

2) 在每个API请求之前自动调用该方法,自动转换所有数据,在POST请求之前使用ActionFilter方法。

a) 我很好奇 Microsoft 是否有 Nuget 包或设置自动将所有内容转换为 某个时区,在 API 之前。 b) 是否有数据序列化技术或最佳方式?这样,我就不必编写自定义代码了。

public static class ObjectDateTimeConverter
{
    public static void ConvertToDefaultTimeZone(object inputObject)
    {
        var type = inputObject.GetType();

        foreach (PropertyInfo property in type.GetProperties())
        {
            if (property.PropertyType == typeof(DateTime) ||    
                property.PropertyType == typeof(DateTime?))
            {
                var newDateTime = (DateTime)(property.GetValue(inputObject));
                newDateTime = DateTimeExtensions.ToPacificTimeZone(newDateTime); // It property is Datetime, call conversion function 
                property.SetValue(inputObject, newDateTime);
            }

            if (property.PropertyType.IsClass && !(property.PropertyType == typeof(string))
            {
                ConvertToDefaultTimeZone(property.GetValue(inputObject));
            }
        }
    }

WebAPI -API拦截器:过滤器属性

在每个 API 请求 DTO 对象之前自动调用 DateConverter

public class DateTimeConverterAsyncFilterAttribute : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext actionExecutingContext, ActionExecutionDelegate next)
    {
        foreach (var actionExecutingContextItem in actionExecutingContext.ActionArguments) // Intercept all requests, and call datetime converter
        {
            if (actionExecutingContextItem.Value != null)
            {
                ObjectDateTimeConverter.ConvertToDefaultTimeZone(actionExecutingContextItem.Value);
            }
        }
        await next();
    }
}

调用自动转换器:放置在控制器或其方法之前

[ServiceFilter(typeof(DateTimeConverterAsyncFilterAttribute))] 
[ApiController]
public class TestController : ControllerBase
{

另外,我听说这种情况下的反射很慢。不确定这是不是真的,我们正在使用 Net Core 2.2

您可以使用 JsonConverter 解决您的问题。 JsonDateTimeConverter 将您的 api 请求和响应中的每个日期时间转换为特定日期时区。

试试这个:

public class JsonDateTimeConverter : DateTimeConverterBase
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue(((DateTime)value).ConvertToDefaultTimeZone());
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            return string.IsNullOrEmpty(reader.Value.ToString())
                ? (object)null
                : reader.Value.ToString().ConvertToDefaultTimeZone();
        }
        catch (Exception)
        {
            return reader.Value;
        }
    }
}

并且在启动时:

        services.AddMvc()
            .AddJsonOptions(options =>
            {
                options.SerializerSettings.Converters.Add(new                     
                      JsonDateTimeConverter());
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);