在调用 API 之前将所有内容转换为特定日期时区
Convert Everything to A Specific Date Timezone before calling an API
我们正在寻求将所有内容转换为 DateTimeZone 太平洋标准时间。
- 数据库团队没有利用 sql
datetimeoffset
- 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);
我们正在寻求将所有内容转换为 DateTimeZone 太平洋标准时间。
- 数据库团队没有利用 sql
datetimeoffset
- 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);