【问题标题】:Asp.net Web API DateTimeOffset set offset from http headerAsp.net Web API DateTimeOffset 设置从 http 标头的偏移量
【发布时间】:2013-12-17 21:39:27
【问题描述】:

在我的项目中,我使用 DateTimeOffset 数据类型作为参数。我意识到偏移量总是“0”。但我需要服务器端的本地时间。为了解决这个问题,我在 http 标头中发送 timezoneoffset,并将在创建 DateTimeOffset 参数时阅读此内容。因此,我创建了一个 ModelBinder 将请求转换为 DateTimeOffset 并从标头中获取 timezoneoffset。这行得通,但是如果任何操作都有一个具有 DateTimeOffset 属性的复杂对象(通过 http POST 以 JSON 格式发送到 web api),那么 modelbinder 没有被执行,并且 DateTimeOffset 属性中的偏移量是“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;
    }
}

【问题讨论】:

  • 就个人而言,我觉得您使用DateTimeOffset 使用了错误的方法。为什么不能在整个应用程序中使用 UTC 时间,而只能在客户端调整时区?
  • 是的,我在我的应用程序中使用 UTC 时间并将 UTC 时间存储到数据库中。但我需要来自客户的偏移量,例如计算一天中正确的开始和结束时间(获取包含一天中所有约会的列表)。

标签: asp.net asp.net-mvc asp.net-web-api json.net


【解决方案1】:

现在我有一个解决方案:我基于 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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    相关资源
    最近更新 更多