Finally Web API OData v4 now supports DateTime type in release 5.5 . Get latest nuget package and don't forget setting this:

config.SetTimeZoneInfo(TimeZoneInfo.Utc);

otherwise the timezone of the dateTime property would be considered as local timezone.

More info: ASP.NET Web API for OData V4 Docs DateTime support


So far, DateTime is not the part of the OASIS OData V4 standard and Web API doesn't support the DateTime type while it do support the DateTimeOffset type.

However, OData Team are working on supporting the DataTime type now. I'd expect you can use the DateTime type in the next Web API release. If you can't wait for the next release, I wrote an example based on the blog . Hope it can help you. Thanks.

Model

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

DB Context

public DbSet<Customer> Customers { get; set; }

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);

Controller

Add the OData Controller as normal.

Test

Customer Data in the DB

Payload

The customers payload


An alternate solution is to patch the project so that DateTime is allowed again - that's what I did, you can get the code here if you want it:

https://aspnetwebstack.codeplex.com/SourceControl/network/forks/johncrim/datetimefixes

I also pushed a NuGet package to make it easy to use, you can obtain the package using the info here:

http://www.nuget.org/packages/Patches.System.Web.OData/5.3.0-datetimefixes

... I don't know if it's ok for me to post a NuGet package containing a patched Microsoft library, I hope it's easier to ask forgiveness than permission.

Note that the work item to officially restore the ability to use DateTime in OData 4 is tracked here: https://aspnetwebstack.codeplex.com/workitem/2072 Please vote for the issue if you'd like to see it; though it looks like it's scheduled for 5.4-beta, so it should be coming one of these days.


This workarounds and the one from http://damienbod.wordpress.com/2014/06/16/web-api-and-odata-v4-crud-and-actions-part-3/, neither work. They work one way only, meaning that quering odata datetimeoffset with the filter command fails because it is not part of the model.

You can no longer filter or sort by these fields or get this error

/Aas/Activities?$top=11&$orderby=CreatedAt

Gives this error:

"code":"","message":"An error has occurred.","innererror":{
  "message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{
    "message":"The specified type member 'CreatedAt' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.","type":"System.NotSupportedException","stacktrace":"   

But this works as it is addressed indirectly:

/Aas/AppUsers%28102%29/AppUserActivities?$expand=Case&$filter=%28Reminder%20ne%20null%20and%20IsComplete%20eq%20null%29&$top=15&$orderby=Reminder&$count=true

Reminder and Iscomplete are date and datetiem from activity through AppUserActivities.

This is wierd that that works. Does anyone have a solution?

I connect to MySQL. There is not a datetimeoffset.

And everyone wonders why no one wants to develop for Microsoft technologies.


Unfortunatly, https://aspnetwebstack.codeplex.com/SourceControl/network/forks/johncrim/datetimefixes fork, given by crimbo doesn`t realy support DateTime.

There is the new fork https://aspnetwebstack.codeplex.com/SourceControl/network/forks/kj/odata53datetime?branch=odata-v5.3-rtm based on OData v5.3 RTM, where DateTime properties in entities and complex types are supported in server answers, client POST/PUT/PATCH requests, $orderby and $filters clauses, function parameters and returns. We start to use it in production code and will support this fork, until DateTime support will return in future official releases.