I’m trying to create a Calendar through the Google API as per the documentation. I am trying to avoid using the Client libraries and do all communication with the API through custom webrequests and so far that has been working nicely but on this particular one I’m struggling with a “parse error”.
Please do not refer to solutions that use the client libraries (service.calendars().insert(…)).
This is a dumbed down version of my code (still not working):
var url = string.Format
(
"https://www.googleapis.com/calendar/v3/calendars?key={0}",
application.Key
);
var httpWebRequest = HttpWebRequest.Create(url) as HttpWebRequest;
httpWebRequest.Headers["Authorization"] =
string.Format("Bearer {0}", user.AccessToken.Token);
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/json";
httpWebRequest.CookieContainer = new CookieContainer();
// Obviously the real code will serialize an object in our system.
// I'm using a dummy request for now,
// just to make sure that the problem is not the serialization.
var requestText =
"{" + Environment.NewLine
+ "\"summary\": \"test123\"" + Environment.NewLine
+ "}" + Environment.NewLine
;
using (var stream = httpWebRequest.GetRequestStream())
using (var streamWriter = new System.IO.StreamWriter(stream))
{
streamWriter.Write(System.Text.Encoding.UTF8.GetBytes(requestText));
}
// GetSafeResponse() is just an extension that catches the WebException (if any)
// and returns the WebException.Response instead of crashing the program.
var httpWebResponse = httpWebRequest.GetSafeResponse();
As you can see, I’ve given up on sending serialized objects for now and I’m just trying to get it working with a very simple dummy request:
{
"summary": "test123"
}
Yet the response is still just:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "parseError",
"message": "Parse Error"
}
],
"code": 400,
"message": "Parse Error"
}
}
The accessToken is valid and not expired, the application key is correct.
What am I doing wrong or missing?
Thanks in advance,
I figured it out and got it working!
While David’s suggestions weren’t the solution by themselves, he put me on the right track by telling me to use a packet sniffer (I ended up using Wireshark but that’s not really the point).
As it turns out, there were two errors in my dumbed down code. One so glaringly obvious that it makes me blush, one slightly more devious.
First of all,
should of course be
as streamWriter.Write does a ToString() on the parameter and Byte[].ToString() just returns “System.Byte[]”. Embarassing!
Secondly, the default UTF8 encoding adds the byte order mark \357\273\277, which also renders the content invalid as far as google is concerned. I found how to fix this problem here on stackoverflow.
So for anyone struggling with this, here is the final solution.
Hope this helps someone!