Google API & # 8594; Create a new calendar & # 8594; Analysis Error

I am trying to create a Calendar through the Google API according to the documentation . I try to avoid using client libraries and do all communication with the API through user web requests, and so far has worked well, but in this particular case I am struggling with a "parse error".

Please do not use solutions using client libraries (service.calendars (). Insert (...)).

This is my 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 refused to send serialized objects, and I'm just trying to get it to work with a very simple dummy request:

 { "summary": "test123" } 

However, the answer is still valid:

 { "error": { "errors": [ { "domain": "global", "reason": "parseError", "message": "Parse Error" } ], "code": 400, "message": "Parse Error" } } 

The accessToken key is valid and not expired, the application key is correct.

What am I doing wrong or missing?

Thanks in advance,

+1
source share
2 answers

I realized this and got his job!

Although David's suggestions were not a solution in 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 quite right).

As it turned out, there were two errors in my disabled code. One of the obvious things is that it makes me blush, a little more insidious.

Primarily,

 using (var streamWriter = new StreamWriter(stream)) { streamWriter.Write(Encoding.UTF8.GetBytes(requestText)); } 

should be of course

 using (var streamWriter = new StreamWriter(stream, Encoding.UTF8)) { streamWriter.Write(requestText); } 

like streamWriter.Write uses ToString () for the parameter and Byte []. ToString () simply returns "System.Byte []". Offensive!

Secondly, the UTF8 encoding by default adds a byte order mark \ 357 \ 273 \ 277, which also makes the content invalid for google. I found how to solve this problem here on stackoverflow.

So, for those struggling with this, here is the final decision.

 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"; // added the character set to the content-type as per David suggestion httpWebRequest.ContentType = "application/json; charset=UTF-8"; httpWebRequest.CookieContainer = new CookieContainer(); // replaced Environment.Newline by CRLF as per David suggestion var requestText = string.Join ( "\r\n", "{", " \"summary\": \"Test Calendar 123\"", "}" ); using (var stream = httpWebRequest.GetRequestStream()) // replaced Encoding.UTF8 by new UTF8Encoding(false) to avoid the byte order mark using (var streamWriter = new StreamWriter(stream, new UTF8Encoding(false))) { streamWriter.Write(requestText); } 

Hope this helps someone!

+1
source

I'm not sure that this will fix your problem, but a few things to note In this case, do not use Environment.NewLine, your network traffic should not change if your code runs on Windows, Mac or Linux. Http 1.1 requires CRLF

You encode the message body as UTF-8, yes, you do not tell the server which encoding you are using. All your charecters have a low ASCII bit, so that doesn't matter, but for completeness, your content type should be

  httpWebRequest.ContentType = "application/json ; charset=UTF-8"; 

Otherwise, I don’t see a problem with your code, maybe a transparent echo proxy (Charles or violinist) can be a good attachment so you can see what your request looks like on a wire. From the calendar they send examples

Request

 POST https://www.googleapis.com/calendar/v3/calendars?key={YOUR_API_KEY} Content-Type: application/json Authorization: Bearer ya29.AHES6ZR3F6ByTg1eKVkjegKyWIukodK8KGSzY-ea1miGKpc X-JavaScript-User-Agent: Google APIs Explorer { "summary": "Test Calendar" } 

Answer

 200 OK - Show headers - { "kind": "calendar#calendar", "etag": "\"NybCyMgjkLQM6Il-p8A5652MtaE/ldoGyKD2MdBs__AsDbQ2rHLfMpk\"", "id": " google.com_gqua79l34qk8v30bot94celnq8@group.calendar.google.com ", "summary": "Test Calendar" } 

Hope this helps, realizing that this is not the case.

+2
source

All Articles