Search code examples
vb.netfullcalendarwebmethod

Populate FullCalendar with events from web method


I'm struggling to get FullCalendar to populate events from a web method.

The web method is as follows:

Imports System.ServiceModel
Imports System.ServiceModel.Activation
Imports System.ServiceModel.Web
Imports Newtonsoft.Json

<ServiceContract(Namespace:="")>
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>
Public Class TestService


  <OperationContract()>
  <WebGet>
  Public Function GetEventList(start As Date, [end] As Date) As String

    Dim a As String
    a = "[  { ""id"": ""46_l"",   ""title"": ""CustomEvent-Chargement"",   ""allDay"": false,  ""start"": ""2018-03-10T14:00:00"", ""end"": ""2018-03-10 15:00""}]"
    Return a

  End Function

End Class

My code to initialise the fullcalendar on the web page is:

var initializeCalendar = function () {
  $('.calendar').fullCalendar({
    events: "../../WebServices/TestService.svc/GetEventList",
    //events: d=[  { "id": "46_l",   "title": "CustomEvent-Chargement",   "allDay": false,  "start": "2018-03-10T14:00:00", "end": "2018-03-10 15:00"}],
    height: screen.height - 160,

  });
};

By using Fiddler, I can see that the web method gets called, and returns the following:

enter image description here

This is a valid JSON string, but FullCalendar doesn't populate the event on the calendar.

If I replace the line

events: "../../WebServices/TestService.svc/GetEventList",

with

events: d=[  { "id": "46_l",   "title": "CustomEvent-Chargement",   "allDay": false,  "start": "2018-03-10T14:00:00", "end": "2018-03-10 15:00"}],

FullCalendar will populate the calendar with the event.

What am I doing wrong?

Thanks in advance for your assistance.

EDIT:

If I change the code for events property of fullcalendar to be

events: function( start, end, timezone, callback ) { 
  //manually specified ajax call to the server:
  $.ajax({
    url: "../../WebServices/TestService.svc/GetEventList",
    data: { "start": start.toISOString(), "end": end.toISOString() }, //pass     in start and end so the server can return the correct events for the time period being displayed
    dataType: "json",
    method: "GET",
  }).done(function(data) { //success
    callback(data.d); //pass the array contained in the "d" property to     fullCalendar
  }).fail(function(jqXHR) { //failure
    alert("An error occurred while fetching events: " + jqXHR.statusText);
  });

}

and the method to return a list of events

Imports System.ServiceModel
Imports System.ServiceModel.Activation
Imports System.ServiceModel.Web
Imports Newtonsoft.Json

Public Class [Event]
  Public Property id() As String
  Public Property title() As String
  Public Property allDay As Boolean
  Public Property start() As String
End Class

<ServiceContract(Namespace:="")>
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>
Public Class TestService

  <OperationContract()>
  <WebGet(ResponseFormat:=WebMessageFormat.Json)>
  Public Function GetEventList(start As String, [end] As String) As List(Of [Event])

    Dim results As New List(Of [Event])()

    results.Add(New [Event]() With {
            .id = "46_l",
            .title = "CustomEvent-Chargement",
            .allDay = False,
            .start = "2018-03-10T14:00:00"
})
    Return results

  End Function

End Class

it returns the object (see Fiddler screenshot below), but doesn't populate the calendar.

enter image description here


Solution

  • Fullcalendar requires the event array to be at the top level of the JSON - i.e. the whole of the JSON is an array. Whereas what your webmethod returns is an object with a single property "d". Therefore fullCalendar doesn't recognise the events, because it doesn't know to look inside that property for the event array.

    This seems to be the normal behaviour of webmethods, and I'm not sure there's really any way round it, so the easiest thing to do is use fullCalendar's custom "events" functionality. Then you can tell it to look specifically in the "d" property of your JSON to find the data.

    events: function( start, end, timezone, callback ) { 
      //manually specified ajax call to the server:
      $.ajax({
        url: "../../WebServices/TestService.svc/GetEventList",
        data: { "start": start.toISOString(), "end": end.toISOString() }, //pass in start and end so the server can return the correct events for the time period being displayed
        dataType: "json",
        method: "GET",
      }).done(function(data) { //success
        callback(data.d); //pass the array contained in the "d" property to fullCalendar
      }).fail(function(jqXHR) { //failure
        alert("An error occurred while fetching events: " + jqXHR.statusText);
      });
    }
    

    See https://fullcalendar.io/docs/events-function for more details.

    You may need to tweak some settings of the ajax call if it doesn't connect properly, but it should be right or nearly right.


    P.S. I assume the data above in your webmethod is just for testing, but I would highly recommend not building your JSON by hand like that - far easier and more robust to use an object-to-JSON serialiser such as JSON.NET instead when dealing with the real event data.