Google API->创建一个新的日历->解析错误 [英] Google API -> Create a new Calendar -> Parse Error

查看:90
本文介绍了Google API->创建一个新的日历->解析错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据的问题.

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".

请不要参考使用客户端库( service.calendars().insert(...))的解决方案.

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"
}

但是响应仍然是:

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

accessToken有效且未过期,应用程序密钥正确.

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

我做错了什么或想念什么?

What am I doing wrong or missing?

预先感谢

推荐答案

我知道了并使其正常工作!

I figured it out and got it working!

尽管David的建议本身并不是解决方案,但他通过告诉我使用数据包嗅探器使我走上了正确的道路(我最终使用了Wireshark,但这并不是重点).

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.

首先

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

当然应该

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

如streamWriter.Write在参数上执行ToString(),而Byte [].ToString()仅返回"System.Byte []".尴尬!

as streamWriter.Write does a ToString() on the parameter and Byte[].ToString() just returns "System.Byte[]". Embarassing!

第二,默认的UTF8编码添加了字节顺序标记\ 357 \ 273 \ 277,这也就Google而言使内容无效.我在stackoverflow上的此处找到了解决方法.

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.

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's suggestion
httpWebRequest.ContentType = "application/json; charset=UTF-8";
httpWebRequest.CookieContainer = new CookieContainer();

// replaced Environment.Newline by CRLF as per David's 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);
}

希望这对某人有帮助!

这篇关于Google API->创建一个新的日历->解析错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆