如何讓 Web API OData v4 使用 DateTime
我有一個相當大的數據模型,我想使用 OData V4 協議使用 Web API OData 公開它。
基礎數據儲存在 SQL Server 2012 數據庫中。該數據庫中有許多 DateTime 列。
當我連接它時,我收到一個錯誤,即 System.DateTime 不受支持。
所以這是我的問題,我該怎麼做才能在 OData 提要中看到我的 DateTime 列?
注意:我無法返回並將所有列更改為 DateTimeOffset 列。
我嘗試更改實體框架 edmx 中列的類型,但它給了我這個錯誤:
指定的成員映射無效。‘MyProject.MyEntity’ 類型中成員 ‘MyPropertyHere’ 的類型 ‘Edm.DateTimeOffset[Nullable=False,DefaultValue=,Precision=]’ 與 ‘SqlServer.datetime[Nullable=False,DefaultValue=,Precision=3] 不兼容’MyDataModel.Store.MyEntity’ 類型中的成員 ‘MyColumnName’。
(基本上認為 DateTime 與 DateTimeOffset 不兼容。)
Web API OData 團隊真的忽略了所有需要使用 SQL Server 類型的人
DateTime嗎?更新:我找到了解決方法,但它們需要更新 EF 模型才能工作。如果可以避免的話,我寧願不必單獨更新數百個屬性。
**更新:這個問題讓我意識到微軟管理其 OData 產品的方式存在嚴重缺陷。有很多問題,但這個是最明顯的。Web API OData 中有大量缺失的功能。 *插入的事務*和排序是其中的兩個。這兩個項目(在 OData 規範中並且在微軟殺死它之前在 WCF 數據服務中)對於任何實際系統都至關重要。
但是,他們沒有將時間花在那些缺少 OData 規範中的功能的關鍵點上,而是決定花時間刪除對許多開發人員非常有幫助的功能。它集中體現了糟糕的管理,優先考慮刪除工作功能而不是添加急需的功能。
我嘗試與 Web API OData 代表討論這些問題,最後,我打開了一個問題/票證,幾天后又關閉了。這就是他們願意做的事情的結束。
正如我所說,Web API OData 的管理還有很多問題(與 DateTime 無關,因此我不會在此列出)。 我一直是 OData 的堅定支持者,但 Web API OData 管理的明顯問題迫使我和我的團隊/公司放棄它。
幸運的是,普通的 Web API 可以設置為使用 OData 語法。設置控制器需要做更多的工作,但最終效果很好。它支持日期時間。(而且似乎擁有至少可以避免做出瘋狂錯誤決定的管理層。)
到目前為止,DateTime 不是OASIS OData V4 標準的一部分,Web API 不支持 DateTime 類型,但它支持 DateTimeOffset 類型。
但是,OData 團隊現在正在努力支持 DataTime 類型。我希望您可以在下一個 Web API 版本中使用 DateTime 類型。如果你等不及下一個版本,我根據 部落格寫了一個例子。希望它可以幫助你。謝謝。
模型
public class Customer { private DateTimeWrapper dtw; public int Id { get; set; } public string Name { get; set; } public DateTime Birthday { get { return dtw; } set { dtw = value; } } [NotMapped] public DateTimeOffset BirthdayOffset { get { return dtw; } set { dtw = value; } } } public class DateTimeWrapper { public static implicit operator DateTimeOffset(DateTimeWrapper p) { return DateTime.SpecifyKind(p._dt, DateTimeKind.Utc); } public static implicit operator DateTimeWrapper(DateTimeOffset dto) { return new DateTimeWrapper(dto.DateTime); } public static implicit operator DateTime(DateTimeWrapper dtr) { return dtr._dt; } public static implicit operator DateTimeWrapper(DateTime dt) { return new DateTimeWrapper(dt); } protected DateTimeWrapper(DateTime dt) { _dt = dt; } private readonly DateTime _dt; }數據庫上下文
public DbSet<Customer> Customers { get; set; }模型
ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet<Customer>("Customers"); var cu = builder.StructuralTypes.First(t => t.ClrType == typeof(Customer)); cu.AddProperty(typeof(Customer).GetProperty("BirthdayOffset")); var customer = builder.EntityType<Customer>(); customer.Ignore(t => t.Birthday); var model = builder.GetEdmModel(); config.MapODataServiceRoute("odata", "odata", model);控制器
正常添加 OData 控制器。
測試
有效載荷
最後,Web API OData v4 現在支持
DateTime5.5 版中的類型。獲取最新的 nuget 包,不要忘記設置:config.SetTimeZoneInfo(TimeZoneInfo.Utc);否則 dateTime 屬性的時區將被視為本地時區。

