如何使用Web API OData v4来使用DateTime

Vac*_*ano 27 .net odata asp.net-web-api asp.net-web-api-odata odata-v4

我有一个相当大的数据模型,我想使用OData V4协议使用Web API OData公开.

基础数据存储在SQL Server 2012数据库中.该数据库中包含许多DateTime列.

当我接线时,我收到一个错误,即不支持System.DateTime.

所以这是我的问题,我该怎么做才能在OData Feed中看到我的DateTime列?

注意:我无法返回并将所有列更改为DateTimeOffset列.

我尝试更改Entity Framework edmx中列的类型,但它给了我这个错误:

指定的成员映射无效."MyProject.MyEntity"类型中成员'MyPropertyHere'的类型'Edm.DateTimeOffset [Nullable = False,DefaultValue =,Precision =]'与'SqlServer.datetime不兼容[Nullable = False,DefaultValue =,Precision = 3] '成员'MyColumnName''类型'MyDataModel.Store.MyEntity'.

(基本上认为DateTime与DateTimeOffset不兼容.)

Web API OData团队真的只是遗漏了需要使用SQL Server类型的所有人DateTime吗?

更新:我找到了相关的解决方法,但他们需要更新EF模型才能使用它们.如果我能避免,我宁愿不必单独更新几百个属性.

更新:这个问题让我意识到微软管理其OData产品的方式存在很大的缺陷.有很多问题,但这个问题最为明显.Web API OData中存在巨大的缺失功能. 插件的交易排序是其中两个.这两个项目(在OData规范中并且在Microsoft杀死它之前在WCF数据服务中)对于任何真实系统都是至关重要的.

但是,他们决定花时间去删除对许多开发人员非常有用的功能,而不是将时间放在那些缺少OData规范功能的关键位置.它体现了糟糕的管理,以便在添加急需的功能时优先删除工作功能.

我尝试与Web API OData代表讨论这些问题,最后,我打开了一个问题/票证,几天后关闭了.那是他们愿意做的结束.

正如我所说,Web API OData的管理还有很多问题(与DateTime无关,所以我不会在这里列出). 我一直是OData的坚定支持者,但Web API OData管理层的明显问题迫使我和我的团队/公司放弃了它.

幸运的是,可以设置普通的Web API以使用OData语法.设置控制器的工作量更大,但最终工作得很好.它支持DateTime.(并且似乎管理层至少可以远离制定疯狂的错误决策.)

Sam*_* Xu 17

到目前为止,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;
}
Run Code Online (Sandbox Code Playgroud)

DB上下文

public DbSet<Customer> Customers { get; set; }
Run Code Online (Sandbox Code Playgroud)

EdmModel

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);
Run Code Online (Sandbox Code Playgroud)

调节器

正常添加OData控制器.

测试

DB中的客户数据

有效载荷

客户有效负载

  • 你确定OData团队正在努力支持DataTime类型吗?目前本期(ODATA-220)被列为OData v5的"未解决":https://issues.oasis-open.org/browse/ODATA/fixforversion/10277/?selectedTab = com.atlassian.jira.jira-projects -plugin:版本摘要面板 (4认同)
  • 他们的"支持"等于将DateTimes转换为DateTimeOffsets.如果你需要过滤日期,它不起作用. (2认同)

Ima*_*sab 17

最后,Web API OData v4现在支持DateTime5.5版本中的类型.获取最新的nuget包,不要忘记设置:

config.SetTimeZoneInfo(TimeZoneInfo.Utc);
Run Code Online (Sandbox Code Playgroud)

否则dateTime属性的时区将被视为本地时区.

更多信息: ASP.NET Web API for OData V4 Docs DateTime support

  • @MaximilianWilson在发行说明中没有提到任何文件.你能提供任何链接吗? (4认同)
  • 为什么有人说它支持“DateTime”?OData V4 支持 Date 和 DateTimeOffset,但不支持 edm:DateTime。如果您查看 OData 服务中的元数据,您将找不到 DateTime。 (2认同)