0

I am passing a model to a view partial containing a form that is being loaded asynchronously. Everything seems to be coming across as expected EXCEPT for a DateTime proprty, what would cause this to happen?

Javascript function

function loadUpdateEventForm(eventID) {
        getEventDetails(eventID, function(dnnEvent) {
            if(dnnEvent != null) {
                $("#updateEventForm").load(urlEditEventForm, dnnEvent, function () {
                    $("form#updateEventForm").submit(function (event) { submitNewEvent(event); });
                });
                dialog = $("#updateEventForm").dialog({ modal: true, width: '80%', position: { my: 'top', at: 'top+150' } });
                console.log(dnnEvent);
                return;
            }
        });
}

Output from console.log(dnnEvent)

Object {EventID: 2524, EventName: "sample", EventDescription: "sample", EventTimeBegin: "/Date(1418709600000)/", UserID: 1}

C# Action method serving partial view

public ActionResult _EditForm(DNNEventUpdateModel dnnEvent)
{
    return View(dnnEvent);
}

DNNEventUpdateModel

public class DNNEventUpdateModel
{
    [Required]
    public int EventID { get; set; }
    [Required]
    public string EventName { get; set; }
    [Required]
    [DataType(DataType.MultilineText)]
    public string EventDescription { get; set; }
    [Required]
    public DateTime EventTimeBegin { get; set; }
    public int UserID { get; set; }

    public string EventTimeBeginForDisplay
    {
        get
        {
            return this.EventTimeBegin.ToShortDateString();
        }

        set
        {
            this.EventTimeBegin = Convert.ToDateTime(value);
        }
    }
}

Update

Just realized I forgot to post how this is coming across in the controller. Here is what I mean about the date:

screenshot

drewwyatt
  • 5,989
  • 15
  • 60
  • 106
  • What happens if you remove the setter for your `EventTimeBeginForDisplay` property? – Matt Johnson-Pint Dec 11 '14 at 21:18
  • 1
    I don't think the MVC model binder knows how to convert a string like "/Date(1418709600000)/" into a proper date time. – rossisdead Dec 11 '14 at 21:22
  • @rossisdead I think you are right. – drewwyatt Dec 11 '14 at 21:28
  • How are you generating the value of `EventTimeBegin` in `dnnEvent`? –  Dec 11 '14 at 21:32
  • @StephenMuecke Events are pulled asynchronously when the calendar is loaded from another controller action. So that property is the result of a JSON Serialized DateTime object. FullCalendar seems to know how to do something with that value, but I'm at a bit of a loss. – drewwyatt Dec 11 '14 at 21:35
  • 1
    Various workarounds are described in the answers to [this question](http://stackoverflow.com/questions/726334/asp-net-mvc-jsonresult-date-format) but you haven't posted the code that shows how you construct the variable `dnnEvent` so hard to determine the best way to handle this –  Dec 11 '14 at 21:46
  • @StephenMuecke `new Date(parseInt(response.TimeBegin.replace("/Date(", "").replace(")/",""), 10))` is ugly, but did the trick. I'm going to use this as a temporary solution and see if I can update the JSON serialization rules for something more permanent. – drewwyatt Dec 11 '14 at 21:53
  • @StephenMuecke If you can post that comment int he form of an answer I will mark it as the accepted solution. – drewwyatt Dec 11 '14 at 21:54

3 Answers3

1

Maybe there is better solution but I send javascript date as string to server, try that.

var date = new Date();
var day = date.getDay();        
var month = date.getMonth();    
var year = date.getFullYear();  
var hour = date.getHours();     
var minute = date.getMinutes(); 
var second = date.getSeconds();

var time = day + "/" + month + "/" + year + " " + hour + ':' + minute + ':' + second;

Then, parse the string in server - side.

DateTime.ParseExact(dateFromClient, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture);

EDIT

I used once the function before sending date.

function EditDate(oldDate) {
    var date = oldDate.split(".");
    return date[2] + "." + date[1] + "." + date[0];
}
  • 2
    Yep, JSON dates don't tend to play well. Just convert the date into a string in the standard format, and the modelbinder should be able to parse it. I'd recommend using something like moment.js for this type of stuff, though. Makes things so much easier: http://momentjs.com/ – Chris Pratt Dec 11 '14 at 21:37
1

The date format EventTimeBegin: "/Date(1418709600000)/" is a function of default JsonScriptSerializer and is discussed in more detail in the answers to this question.

You can parse the value to a string using

new Date(parseInt(response.TimeBegin.replace("/Date(", "").replace(")/",""), 10))

Other options including formatting the date in the controller method, for example

var data = new
{
  ....
  TimeBegin = YourDate.ToString("o"),
  ....
};
return Json(data, JsonRequestBehavior.AllowGet);

and in the script

new Date(response.TimeBegin);

or using another json serializer such as Json.NET which serializes dates in ISO format.

This blog also discusses some client side and server side solutions.

Community
  • 1
  • 1
0

It looks like you're doing a form post.

$("form#updateEventForm").submit(function (event) { submitNewEvent(event); });

So the model binder on the MVC side does NOT use a JSON parser. I am guessing submitNewEvent stuffs the values from the event into form fields. since the JSON model binder is not involved, the form field coantaining a JSON formatted date, is not handled properly.

MVC will handle JSON posts if you used something like $.post and posted the JSON string verbatim instead of stuffing a form. This way the JSON parser is used during model binding, and the JSON formatted date will be properly handled.

Otherwise if you're committed to using your form post, you need to populate the form with a properly formatted date before posting it. Which would be 'YYYY-MM-DD' or in other words <input value='2014-01-30'>. You can't blindly take a JSON formatted date string and plug it into a form field.

Of course I'm making assumptions based on javascript function calls you have that we don't have the code for.

AaronLS
  • 37,329
  • 20
  • 143
  • 202