Asp.net Web API DateTimeOffset设置了与http标头的偏移量



在我的项目中,我使用DateTimeOffset数据类型作为参数。我意识到偏移量总是"0"。但我需要服务器端的本地时间。为了解决这个问题,我在http头中发送了timezoneoffset,并将在创建DateTimeOffset参数时读取它。因此,我创建了一个ModelBinder来将请求转换为DateTimeOffset,并从标头中获取timezoneoffset。这是可行的,但如果任何操作都有一个具有DateTimeOffset属性的复杂对象(通过http POST以JSON格式发送到web api),则模型绑定器没有执行,DateTimeOffsets属性中的偏移量为"0"。有没有什么方法可以自定义从JSON创建对象的行为,这样我就可以从http头中获得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头加载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;
    }
}

相关内容

  • 没有找到相关文章

最新更新