2013-12-17 34 views
2

在我的項目中,我使用DateTimeOffset數據類型作爲參數。我意識到偏移總是「0」。但我需要當地時間在服務器端。爲了解決這個問題,我發送了http頭中的timezoneoffset,並在創建DateTimeOffset參數時讀取它。因此,我創建了一個ModelBinder將請求轉換爲DateTimeOffset,並從頭中獲取timezoneoffset。這是有效的,但是如果任何操作具有帶DateTimeOffset屬性的複雜對象(通過http POST以JSON格式發送到web api),所以modelbinder未執行且DateTimeOffset屬性中的偏移量爲「0」。有什麼方法可以自定義從JSON創建對象的行爲,以便我可以從http頭獲取timezoneoffset?Asp.net Web API DateTimeOffset從http頭設置偏移量

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; 
    } 
} 
+0

就我個人而言,我覺得你使用'DateTimeOffset'錯誤的方法。爲什麼不能在整個應用程序中使用UTC時間,只能在客戶端調整時區? – Dai

+0

是的,我在我的應用程序中使用UTC時間並將UTC時間存儲到數據庫中。但我需要客戶端的偏移量,例如計算一天的正確開始和結束時間(以獲得一天中所有約會約會的列表)。 –

回答

4

現在我有一個解決辦法:我實現了一個自己的JsonConverter基於IsoDateTimeConverter至極的裝載來自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; 
    } 
} 
相關問題