-1

I am using Microsoft's Entity Framework 6.1.3. with Database First (from an Azure SQL Server instance). The automatically generated Entity looks like this - the database column is datetime2(0) but really I just want to persist the date but that's another discussion:

public partial class Liquidated
{
    public long ID { get; set; }
    public System.DateTime LiquidationDate { get; set; }
    public string Comment { get; set; }
}

The auto-generated Controller:

    // POST: api/Liquidations
    [ResponseType(typeof(Liquidated))]
    public IHttpActionResult PostLiquidated(Liquidated liquidated)
    {

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

The unit test using RestSharp:

        var client = new RestClient("http://localhost:64185/api/Liquidations");
        var request = new RestRequest(Method.POST);

        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", "bearer " + token.access_token);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("audience", "Any");
        request.AddHeader("accept-language", "en-gb");
        request.AddHeader("accept", "application/json");

        var liquidation = new Liquidated();

        liquidation.LiquidationDate = DateTime.Now;
        liquidation.Comments = "Updated group name 1";

        request.AddObject(liquidation);

        IRestResponse<Liquidated> response = client.Execute<Liquidated>(request);

But when I inspect the ModelState in the Controller it is not valid and shows the following format error for LiquidationDate:

"The value '18/04/2017 14:26:12' is not valid for LiquidationDate."

I've searched many posts, tried to force the formatting (is it a question of date formatting between C# entities and SQL Server?) but I can't see what I'm doing wrong. Any help is much appreciated!

Bexbissell
  • 25
  • 6
  • 1
    The model state error is because you are posting the wrong data to the API, it's nothing to do with Entity Framework. I would guess it's most likely something to do with date format (`dd/mm/yyy` vs `mm/dd/yyyy` for example) – DavidG Apr 18 '17 at 14:19
  • It is recommended using DateTimeOffset with EF. http://stackoverflow.com/questions/9389954/entity-framework-mapping-datetimeoffset-to-sql-server-datetime – Steve McCormack Apr 18 '17 at 14:22
  • @DavidG - thanks for the comment. I removed any date data from the unit test post and that worked. I then replaced the datetime in the client-side class and changed it to a string, of which I have complete formatting control i.e. yyyy-MM-dd. I think I was putting too much faith into RestSharp's ability to format appropriately - not sure it is even possible but will find out. – Bexbissell Apr 18 '17 at 14:45

2 Answers2

0

If posting JSON data to Web API, make sure that date values are sent in ISO 8601 format (2017-04-18T14:22:59Z). Else you run into problems with the modelbinder.

Example of JS function to convert UTC Javascript date object to ISO 8601 string (date only without time):

/// <summary>
/// Takes a utc js date and converts it to a iso8601 utc string
/// </summary>
GlobalJsHelpers.Iso8601FromUtc = function(utcDate) {
    //create a two digit month string (01-12)
    var month = ('0' + (utcDate.getUTCMonth() + 1)).substr(-2);
    //create a two digit day string (01-31)
    var day = ('0' + utcDate.getUTCDate()).substr(-2);
    return utcDate.getUTCFullYear() + '-' + month + '-' + day;
};

See Why is RestSharp deserializing two dates differently? on how to trick RestSharp.

Community
  • 1
  • 1
Georg Patscheider
  • 9,357
  • 1
  • 26
  • 36
0

Following on from @DavidG's comment I changed the client-side Liquidated class to contain a string instead of datetime:

public partial class Liquidated
{
    public long ID { get; set; }
    public string LiquidationDate { get; set; }
    public string Comments { get; set; }
}

and then did the formatting outside of RestSharp:

        var client = new RestClient("http://localhost:64185/api/Liquidations");
        var request = new RestRequest(Method.POST);
        request.AddHeader("postman-token", "a95ce9b5-8c7f-e223-faa6-3768f7edd10c");
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("authorization", "bearer " + token.access_token);
        request.AddHeader("content-type", "application/x-www-form-urlencoded");
        request.AddHeader("audience", "Any");
        request.AddHeader("accept-language", "en-gb");
        request.AddHeader("accept", "application/json");

        var liquidation = new Liquidated();

        liquidation.LiquidationDate = DateTime.Now.ToString("yyyy-MM-dd");
        liquidation.Comments = "Updated group name 1";

        // request.DateFormat = "yyyy-MM-dd"; // This is ignored by RestSharp
        request.AddObject(liquidation);

        IRestResponse<Liquidated> response = client.Execute<Liquidated>(request);

Having read the RestSharp GitHub issue log: https://github.com/restsharp/RestSharp/issues/629, there are no plans to support this facility.

Thanks for pointing me in the right direction.

Bexbissell
  • 25
  • 6