James
James

Reputation: 1501

Full Calendar GetEvents() method call not working

I am trying to fetch events from my database, but I can't get it to work. The events aren't being displayed in my calendar and in my web console, I get:

Failed to load resource: the server responded with a status of 500 (Internal Server Error)

Exception thrown:

The parameters dictionary contains a null entry for parameter 'start' of non-nullable type 'System.Double' for method 'System.Web.Mvc.JsonResult GetEvents(Double, Double)' in 'ForecastCalendar.Controllers.HomeController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters

Here is the methods in my controller that I use to fetch events:

public JsonResult GetEvents(double start, double end)
{
    var events = new List<Event>();

    var dtstart = ConvertFromUnixTimestamp(start);
    var dtend = ConvertFromUnixTimestamp(end);

    DateTime currStart;
    DateTime currEnd;

    foreach (Event ev in db.Events)
    {
        currStart = Convert.ToDateTime(ev.StartDate);
        currEnd = Convert.ToDateTime(ev.EndDate);

        events.Add(new Event()
        {
            ID = ev.ID,
            Title = ev.Title,
            StartDate = currStart,
            EndDate = currEnd,
            AllDay = true,
            EventType = ev.EventType,
            Hours = ev.Hours
        });
    }

    var rows = events.ToArray();
    return Json(rows, JsonRequestBehavior.AllowGet);
}

private static DateTime ConvertFromUnixTimestamp(double timestamp)
{
    var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
    return origin.AddSeconds(timestamp);
}

Below is my event model:

using System;
using System.ComponentModel.DataAnnotations;

namespace ForecastCalendar.Models
{
    public enum EventType
    {
        BAU,
        Project,
        AnnualLeave
    }

    public class Event
    {
        public int ID { get; set; }

        [Required]
        [DataType(DataType.Date, ErrorMessage = "Please enter a valid date.")]
        [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
        [Display(Name = "Start Date")]
        public DateTime StartDate { get; set; }

        [Required]
        [DataType(DataType.Date, ErrorMessage = "Please enter a valid date.")]
        [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
        [Display(Name = "End Date")]
        public DateTime EndDate { get; set; }

        [Required]
        [StringLength(50, ErrorMessage = "Title cannot be longer than 50 characters.")]
        [RegularExpression(@"^[a-zA-Z- ]+$", ErrorMessage = "Invalid characters used. A-Z or a-z, '-' and ' ' allowed.")]
        [Display(Name = "Title")]
        public string Title { get; set; }

        [Required]
        [EnumDataType(typeof(EventType), ErrorMessage = "Submitted value is not valid.")]
        [Display(Name = "Type")]
        public EventType? EventType { get; set; }

        [Required]
        public double Hours { get; set; }

        [Required]
        public Boolean AllDay { get; set; }

        [Timestamp]
        public byte[] RowVersion { get; set; }

        public virtual Person Person { get; set; }
    }
}

Here is the JavaScript where the calendar is rendered.

@{
    ViewBag.Title = "Home Page";
}

@Styles.Render("~/Content/fullcalendar")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/fullcalendar")

<br />
<div class="container">
    <div id="calendar"></div>
</div>
<br />

<script type="text/javascript">
$(document).ready(function () {
    $('#calendar').fullCalendar({
        header: {
            left: 'title',
            center: '',
            right: 'prev,next today' },
        defaultView: 'month',
        weekends: false,
        editable: false,
        events: "/Home/GetEvents/"
    });
});
</script>

Any help is greatly appreciated.

EDIT:

I have changed my GetEvents() method to conform to the event type in full calendar.

public JsonResult GetEvents(double start, double end)
        {
            var fromDate = ConvertFromUnixTimestamp(start);
            var toDate = ConvertFromUnixTimestamp(end);

            var rslt = db.Events;

            List<Event> result = new List<Event>();

            foreach (var item in rslt)
            {
                Event ev = new Event();
                ev.ID = item.ID;
                ev.Title = item.Title;
                ev.Hours = item.Hours;
                ev.StartDate = item.StartDate;
                ev.EndDate = item.EndDate;
                ev.EventType = item.EventType;
                ev.AllDay = ev.AllDay;
            }

            var resultList = result;

            var eventList = from e in resultList
                            select new
                            {
                                id = e.ID,
                                title = e.Title,
                                start = e.StartDate,
                                end = e.EndDate,
                                allDay = e.AllDay
                            };

            var rows = eventList.ToArray();
            return Json(rows, JsonRequestBehavior.AllowGet);
        }

Upvotes: 1

Views: 2216

Answers (2)

Myshkin
Myshkin

Reputation: 96

Old question but I have just run into the same problem after following some tutorials on how to implement the GetEvents method. On my end the calendar never hit the GetEvents method when I had it set up to expect two parameters of type double like this

public JsonResult GetEvents(double start, double end) 

When looking at the error I saw that the calendar tried calling the following method:

/GetEvents?start=2013-12-01&end=2014-01-12&_=1386054751381

My calendar's defaultview is 'month'. Changing my GetEvents method to expect two strings

public JsonResult GetEvents(string start, string end)

and voila, when I refresh the page the Calendar tries to refresh and calls my GetEvents method. However, because you are now dealing with strings and not doubles you also need to change this part of your code:

var dtstart = ConvertFromUnixTimestamp(start);
var dtend = ConvertFromUnixTimestamp(end);

to deal with the strings (formatted like this: "2013-12-01")

Upvotes: 0

Mario Levrero
Mario Levrero

Reputation: 3367

Check the parameters you are receiving server side at GetMethods, that has a signature waiting two Double parameters, are not null.

In addition, you are sending a JSON object directly from your Model Event object. Then, client-side, this JSON object is directly injected as a source in fullcalendar. But fullcalendar is expecting for properties named as in the documentation, so start and title are mandatory properties.

From fullcalendar doc Event object

'start'

The date/time an event begins. Required.

A Moment-ish input, like an ISO8601 string. Throughout the API this will become a real Moment object.

But your JSON object has no start property, but StartDate.

Now you can:

  • Change your model to match the fullcalendar properties.
  • Map server side the properties, so you return the JSON with the proper names.
  • ...You could also map them client-side, but based on your current code would be tedious and dirty

Anyway, be sure that at client side you have your objects with start property.

Upvotes: 1

Related Questions