在我的项目中,我使用 DateTimeOffset 数据类型作为参数。我意识到偏移量总是“0”。但我需要服务器端的本地时间。为了解决这个问题,我在 http header 中发送 timezoneoffset 并将在创建 DateTimeOffset 参数时读取它。因此,我创建了一个 ModelBinder 来将请求转换为 DateTimeOffset 并从标题中获取 timezoneoffset。这是可行的,但是如果任何操作具有具有 DateTimeOffset 属性的复杂对象(通过 http POST 以 JSON 格式发送到 web api),则不会执行模型绑定(bind)器并且 DateTimeOffset 属性中的偏移量为“0”。有什么方法可以自定义从 JSON 创建对象的行为,以便我可以从 http header 中获取 timezoneoffset?
public class DateTimeOffsetModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(DateTimeOffset))
{
return false;
}
var timezoneOffsetMinutes = actionContext.Request.Headers
.Where(h => String.Equals(h.Key, "TimezoneOffsetMinutes", StringComparison.InvariantCultureIgnoreCase))
.SelectMany(h => h.Value)
.FirstOrDefault()
.ParseAsNullableInteger();
if (!timezoneOffsetMinutes.HasValue)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Http header dosn't contains 'timezoneoffsetminutes'.");
return false;
}
TimeSpan timezoneOffset = TimeSpan.FromMinutes(timezoneOffsetMinutes.Value);
ValueProviderResult value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
DateTime date;
if (!DateTime.TryParse(value.AttemptedValue, out date))
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Can't parse parameter '" + bindingContext.ModelName + "' to DateTime.");
return false;
}
date = date.ToUniversalTime();
bindingContext.Model = new DateTimeOffset(date).ToOffset(timezoneOffset);
return true;
}
}
最佳答案
现在我有了一个解决方案:我基于 IsoDateTimeConverter 实现了一个自己的 JsonConverter ,它从 http header 加载 timezoneoffset 并将其正确设置为 DateTimeOffset。
public class DateTimeOffsetConverter : IsoDateTimeConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
object baseResult = base.ReadJson(reader, objectType, existingValue, serializer);
DateTimeOffset? date = baseResult as DateTimeOffset?;
if (date.HasValue)
{
//timezone offset
int? timezoneOffsetMinutes = HttpContext.Current.Request.Headers["TimezoneOffsetMinutes"].ParseAsNullableInteger();
TimeSpan? timezoneOffset = timezoneOffsetMinutes.HasValue
? TimeSpan.FromMinutes(timezoneOffsetMinutes.Value)
: (TimeSpan?)null;
return timezoneOffset.HasValue
? date.Value.ToOffset(timezoneOffset.Value)
: date.Value;
}
return baseResult;
}
}
关于Asp.net Web API DateTimeOffset 从 http header 设置偏移量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20645227/