Unknown issue with JSON string formatting - fullcalendar

I'm passing data to my implementation of the FullCalendar via JSON.
My feed looks ok, but for some reason the calendar doesn't display any data.
Here is an example of my JSON feed:
[{
"title":"Resourse for Paths ",
"start":"2011-11-08T07:30:00Z",
"end":"2011-11-08T10:30:00Z",
"allDay":false
}]
According to the FullCalendar manual, everything looks ok, but I am getting no data at all.
Does anyone see anything that I don't?
Here is the code that generates the feed:
Private Function makejsonoftable(ByVal table As DataTable, ByVal e As makejson) As String
Dim sb As New StringBuilder()
Dim cultureName As String = "en-US"
Dim culture As CultureInfo = New CultureInfo(cultureName)
Dim fieldvalue As String
For Each dr As DataRow In table.Rows
If sb.Length <> 0 Then
sb.Append(",")
End If
sb.Append("{")
Dim sb2 As New StringBuilder()
For Each col As DataColumn In table.Columns
Dim fieldname As String = col.ColumnName
If TypeOf (dr(fieldname)) Is Boolean Then
fieldvalue = Convert.ToBoolean(dr(fieldname))
Else
If TypeOf (dr(fieldname)) Is DateTime Then
fieldvalue = Convert.ToDateTime(dr(fieldname))
Else
fieldvalue = dr(fieldname).ToString()
End If
End If
If sb2.Length <> 0 Then
sb2.Append(",")
End If
If TypeOf (dr(fieldname)) Is Boolean Then
sb2.Append(String.Format("""{0}"":{1}", fieldname, fieldvalue.ToLower))
Else
If TypeOf (dr(fieldname)) Is DateTime Then
sb2.Append(String.Format("""{0}"":""{1:ddd, dd MMM yyyy HH':'mm':'ss 'EST'}""", fieldname, Convert.ToDateTime(fieldvalue)))
Else
sb2.Append(String.Format("""{0}"":""{1}""", fieldname, fieldvalue))
End If
End If
Next
sb.Append(sb2.ToString())
sb.Append("}")
Next
If e = makejson.e_with_square_brackets Then
sb.Insert(0, "[")
sb.Append("]")
End If
Return sb.ToString()
End Function
Public Enum makejson
e_without_square_brackets
e_with_square_brackets
End Enum
Thanks

My JSON feed for FullCalendar is written in PHP. I get the event info from my MySQL database and format it in PHP, and output it as a JSON file for the calendar. This is part of the code:
$jsonfeed = "[
";
while($row = mysql_fetch_array($result))
{
// some formatting happens here, then:
$jsonfeed .= "
{
\"title\" : \"" . $this_group . "\",
\"start\" : \"" . $row[formatDate] . " " . $row[formatStart] . "\",
\"end\" : \"" . $row[formatDate] . " " . $row[formatFinish] . "\",
\"description\" : \"" . $description . "\",
\"url\" : \"http://mysite.com/" . $row[id] . "\",
\"allDay\" : false
},";
}
// remove the final comma, add final ]
$jsonfeed = substr($jsonfeed, 0, -1) . "
]
";
This is what ended up working for me, after quite a number of variations. Apparently, I needed to have those line breaks (it just wouldn't work without them). So, that's something you might want to try. Also, I'm using a local time zone, so I didn't need the final "Z" and I have a space instead of the "T" between date and time. I don't know if that will affect your code, but it's something else to try.
Also, have you tried putting your JSON code through a validator, to check it?

Just the other day I was doing some debugging and introduced some linefeeds/carriage returns into some JSON which was used in an AJAX response. Safari did not mind but Firefox did not like it because linefeeds and carriage returns are not valid JSON, so that could well be your problem.

I think the problem is the quotes around the variables (aka: title, start, end, and allday). Remove the quotes and see what happens.
EDIT: An example from docs
$('#calendar').fullCalendar({
eventSources: [
// your event source
{
url: '/myfeed.php', // use the `url` property
color: 'yellow', // an option!
textColor: 'black' // an option!
}
// any other sources...
]
});

Related

DateTime.TryParse returning wrong (IMO) answer

I have an old asp classic VB script that was converted to run in VB .NET long ago that is a mess but I can't get approval to rewrite it yet.
In there it had a function that takes a string and attempts to handle it properly based on its content.
It was originally written as:
Public Shared Function fx(ByVal _str As String) As String
If IsDate(_str) Then
'Dates have to be formated just right for MySQL to accept them
fx = DatePart("yyyy", _str) & "-" & DatePart("m", _str) & "-" & DatePart("d", _str)
ElseIf IsNumeric(_str) Then
'Numbers go in just fine
fx = _str
ElseIf Len(_str) > 0 Then
'If it's not a date and not a number then treat it as a text field and filter it so that MySQL will take it
_str = Trim(_str) 'First trim off any leading and trailing spaces
_str = Replace(_str, "\", "\\") 'Change all \ to \\
_str = Replace(_str, "'", "''") 'Change all ' to ''
fx = _str
Else
fx = ""
End If
End Function
My problem comes when I use pass fx the value "11.16" and it says "Oh yes, that's a date - 2015/11/16"
I tried using success = DateTime.TryParse(_str,tempDate) but it behaves the same.
What is the best way to do this if _str being passed in can be anything from a blank string to a date to a dollar amount to a street address? The obvious is to rewrite the calling code but with the legacy code that's not terribly practical. Any suggestion appreciated.
Thanks!
Andrew Whitaker's answer of TryParseExact and an array of date formats is the best answer to my particular situation.
Public Shared Function fx(ByVal _str As String) As String
If IsDate(_str) Then
'Dates have to be formated just right for MySQL to accept them
fx = DatePart("yyyy", _str) & "-" & DatePart("m", _str) & "-" & DatePart("d", _str)
ElseIf IsNumeric(_str) Then
'Numbers go in just fine
fx = _str
ElseIf Len(_str) > 0 Then
'If it's not a date and not a number then treat it as a text field and filter it so that MySQL will take it
_str = Trim(_str) 'First trim off any leading and trailing spaces
_str = Replace(_str, "\", "\\") 'Change all \ to \\
_str = Replace(_str, "'", "''") 'Change all ' to ''
fx = _str
Else
fx = ""
End If
End Function

How does one set a property of a JsonObject dynamically?

I am using a method of passing Json to and from my markup using jquery and ajax. This can be described in more detail on this page: http://blogs.telerik.com/aspnet-ajax/posts/12-04-27/the-present-and-future-of-using-json-in-webforms.aspx
In this snippet of code, I try to set the object's value dynamically by setting a string variable named "test" to a business object's value:
Dim objOrder As Object = New JsonObject()
For Each Order As BoVendorOrder In Orders
Dim Vendor As New BoVendor(Order.VendorID)
Dim test As String = Order.VendorOrderID
objOrder.test = Vendor.VendorName + " - " + Order.VendorOrderPoNumber
Next
I left out some code for the sake of brevity. The goal is to get the objOrder.test to be equal to the VendorOrderID (a number in our SQL database) so that the JSON looks like this:
{
"123456": "VendorName - PONumber",
"678901": "VendorName - PONumber"
}
Any of you guys out there know how to do this?
Do you really need the order IDs to be properties of the object? It might be easier to just return a serialized Dictionary(Of String, String). You could still look up by order ID and it would be easier to loop over than the props of the Javascript object.
Here's an example of what you'd need to do using the dictionary approach:
Dim OrdersDict as New Dictionary(Of String, String)()
For Each Order as BoVendorOrder In Orders
If Not OrdersDict.ContainsKey(Order.VendorOrderID) Then
OrdersDict.Add(Order.VendorOrderID, Vendor.VendorName + " - " + Order.VendorOrderPoNumber)
End If
Next
' Serialize the dictionary object to JSON
' Using System.Web.Script.Serialization.JavascriptSerializer:
Dim Serializer As New JavaScriptSerializer
If MaxLength Then Serializer.MaxJsonLength = Int32.MaxValue
Dim x as String = Serializer.Serialize(OrdersDict) 'Return or response.write x as needed
'or
'Using JSON.net
Dim x as String = JsonConvert.SerializeObject(OrdersDict) 'Return or response.write x as needed

How to deal with SqlDataReader null values in VB.net

I have the follwoing code that performs a query and returns a result. However, I looked around and found some examples to take care of null values but I get an error: "Invalid attempt to read when no data is present." I also got the error: "Conversion from type 'DBNull' to type 'Decimal' is not valid."
Can someone help me out with this code to prevent null values from crashing my program?
Private Sub EFFICIENCY_STACKRANK_YTD(ByVal EMPLOYEE As String)
Dim queryString As String = "SELECT " & _
" (SELECT CAST(SUM(TARGET_SECONDS) AS DECIMAL)/ CAST(SUM(ROUTE_SECONDS) AS DECIMAL) FROM dbo.APE_BUSDRIVER_MAIN WITH(NOLOCK) WHERE APE_AREA_OBJID = " & lblAreaOBJID.Text & " AND EMPLOYEE_NAME = '" & EMPLOYEE & "' AND YEAR_TIME = '" & cbYear.Text & "' AND ACTIVE = 1) AS RESULT1" & _
" FROM dbo.APE_BUSDRIVER_MAIN "
Using connection As New SqlConnection(SQLConnectionStr)
Dim command As New SqlCommand(queryString, connection)
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
If reader.Read Then
RESULT1 = reader("RESULT1")
Else
RESULT1 = 0
End If
End Using
End Sub
You have opened the reader, but have not asked it to actually read anything.
After this line:
Dim reader As SqlDataReader = command.ExecuteReader()
add
If reader.Read() Then
and wrap the result reading into this if statement, i.e.
If reader.Read() Then
Dim index As Integer = reader.GetOrdinal("RESULT1")
If reader.IsDBNull(index) Then
RESULT1 = String.Empty
Else
RESULT1 = reader(index)
End If
End If
Note that this works because your SQL should only return a single record. In the event that you were reading multiple records, you would need to call the Read statement in a loop until there were no more records, i.e.
Do While reader.Read()
Loop
I wanted to provide another, more-advanced, answer as an option. Many classes can be extended in .NET like this.
If you are regularly performing "Is NULL" checks like this in your applications, you can choose to extend the DataReader class once to have additional functions available everywhere in your application. Here is an example that creates an extension called "ReadNullAsString()" onto the data reader class. This makes a function that always returns String.Empty when a DbNull is encountered.
Part 1, place this module code in a new class file in App_Code if application is a website, otherwise place where ever you prefer. There are two overloads, one for the field's ordinal position (aka index), and one for the field's ColumnName.
Public Module DataReaderExtensions
''' <summary>
''' Reads fieldName from Data Reader. If fieldName is DbNull, returns String.Empty.
''' </summary>
''' <returns>Safely returns a string. No need to check for DbNull.</returns>
<System.Runtime.CompilerServices.Extension()> _
Public Function ReadNullAsEmptyString(ByVal reader As IDataReader, ByVal fieldName As String) As String
If IsDBNull(reader(fieldName)) Then
Return String.Empty
Else
Return reader(fieldName)
End If
Return False
End Function
''' <summary>
''' Reads fieldOrdinal from Data Reader. If fieldOrdinal is DbNull, returns String.Empty.
''' </summary>
''' <returns>Safely returns a string. No need to check for DbNull.</returns>
<System.Runtime.CompilerServices.Extension()> _
Public Function ReadString(ByVal reader As IDataReader, ByVal fieldOrdinal As Integer) As String
If IsDBNull(reader(fieldOrdinal)) Then
Return ""
Else
Return reader(fieldOrdinal)
End If
Return False
End Function
End Module
Step 2, call the new extension like so:
' no need to check for DbNull now, this functionality is encapsulated in the extension module.
RESULT1 = reader.ReadNullAsEmptyString(index)
'or
RESULT1 = reader.ReadNullAsEmptyString("RESULT1")

Using LINQ to query XML and return empty string if no data is present

What I'm trying to do is to write a generic rss reader that I plug in any URL into without worry if the feed has all the common properties. For instance in my example below I'm looking for pubDate, however if no pubDate exists in the xml I'd like to return the current Date. I cannot seem to get the syntax right though. Any suggestions?
Dim xmldoc As New XDocument
xmldoc = XDocument.Load(url)
Dim feeds = From feed In xmldoc.Descendants("item") Select New With { _
Key .Title = feed.Element("title").Value, _
Key .Link = feed.Element("link").Value, _
Key .Description = feed.Element("description").Value, _
Key .PubDate = If(feed.Element("pubDate").Value Is Nothing, Date.Now.ToString, feed.Element("pubDate").Value)}
For Each item In feeds
Response.Write("" & item.Title & " - " & item.PubDate & "<br />")
Response.Write(item.Description & "<hr />")
Next
Try this
Key .PubDate = IIf(feed.Element("pubDate") Is Nothing, Date.Now.ToString, feed.Element("pubDate").Value)
instead of feed.Element("pubDate").Value Is Nothing write feed.Element("pubDate") Is Nothing!

Getting the Request Variables from an ASP.NET page

I wrote the following function that works about 95% of the time, but I need it to work 100% (obviously):
Public Shared Function getPassedVars() As String
Const keyCount As Integer = 54 ' 54 seems to be the number of parameter keys passed by default (for this web_app).
' there are more if there is a form involved (ie. from search page)
Dim oParams As String = ""
Try
With HttpContext.Current
If .Request.Params.AllKeys.Count > keyCount Then
For i As Integer = 0 To (.Request.Params.AllKeys.Count - (keyCount + 1))
oParams &= String.Format("{0}={1}{2}", .Request.Params.Keys.Item(i), .Request.Params(i), IIf(i < .Request.Params.AllKeys.Count - (keyCount + 1), ";", ""))
Next
End If
End With
Return oParams
Catch ex As Exception
Return Nothing
End Try
End Function
It scrubs the Request.Params object for passed variables, which are in the beginning of the array (the remaining ones are ASP parameters). I am pretty sure I've seen a different way to get these parameters, but I haven't been able to figure it out. Any suggestions?
EDIT
So it looks like I can use the Request.URL.Query to achieve this, I will investigate this and post back.
Here is what I came up with:
Public Shared Function getPassedVars() As String
Dim oParams As String = ""
Dim qString As String = ""
Dim oSplit As New List(Of String)
Try
With HttpContext.Current
qString = .Request.Url.Query
If qString.Length > 0 Then 'do we have any passed variables?
If qString.StartsWith("?") Then qString = qString.Remove(0, 1) 'remove leading ? from querystring if it is there
oSplit.AddRange(qString.Split("&"))
For i As Integer = 0 To oSplit.Count - 1
oParams &= String.Format("{0}{1}", oSplit.Item(i), IIf(i < oSplit.Count - 1, ";", ""))
Next
Return oParams
Else
Return Nothing
End If
End With
Catch ex As Exception
Return Nothing
End Try
End Function
So far so good.
Request.QueryString is a NameValueCollection, so the easiest way to get the "parameters" is to do the following:
foreach (String s in Request.QueryString) {
Response.Write(s + " = " + Request.QueryString[s]);
}
Where is your function located? If it's executing in the page's code behind then you definitely do not need to use the HttpContext variable.
It looks like you are trying to get values from the query string.
For example, for this URL:-
http://www.tempuri.org/mypage.aspx?param1=x&param2=y
I assume you want retreive the values of the query string parameters param1 and param2?
If so, just use:-
Dim param1 as String = Request.QueryString("param1")
Otherwise, if these parameters are contained in a form (an HTTP POST request) then use the method which Mitchel Sellers suggests.
If you know the name you can use the following to get it by key value
Dim myParamValue as String = Request.Form("MyKeyName")
Otherwise, you can loop through the form collection, by key etc, to get the values. The key is, do you really need to be parsing all 54 items? Or are you simply looking for a few specific values?
httpcontext.Current.Request.QueryString("KeyName")
Request.Params will contain the query parameters you're after.
There's no need to parse the info from Request.URL since it's already done for you.

Resources