ContactsRequest.Insert(feedUri,newEntry)有时会失败,并出现System.Net.ProtocolViolationException [英] ContactsRequest.Insert(feedUri, newEntry) sometimes fails with System.Net.ProtocolViolationException

查看:105
本文介绍了ContactsRequest.Insert(feedUri,newEntry)有时会失败,并出现System.Net.ProtocolViolationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这段代码可用于在我创建的测试gmail帐户中添加联系人:

I have this piece of code for adding a contact in a test gmail account I created:

public class SomeClass
{
    private const string ClientId = "someclientid"
    private const string CliendSecret = "muchsecretwow";

    private const string ApplicationName = "such app";
    private const string RedirectUri = "http://localhost";

    private const string Scopes = "https://www.google.com/m8/feeds/";
    private OAuth2Parameters _parameters;

    private string _accessToken, _refreshToken;
    public void GoogleApiCallAddContact() {
        GetOAuthParameters();
        if (!GetTokensFromMemory())
            throw new Exception("please create new authorization code");
        _parameters.AccessToken = _accessToken;
        _parameters.RefreshToken = _refreshToken;

        var settings = new RequestSettings(ApplicationName, _parameters);


        var cr = new ContactsRequest(settings);

        var newEntry = new Contact {
            Name = new Name {
                FullName = "John Foo",
                GivenName = "John",
                FamilyName = "Foo",
            },
            Content = "some info"
        };

        newEntry.Emails.Add(new EMail {
            Primary = true,
            Rel = ContactsRelationships.IsOther,
            Address = "foo@somemailserver.com"
        });


        var feedUri = new Uri("https://www.google.com/m8/feeds/contacts/default/full");


        cr.Insert(feedUri, newEntry);



    }

    private void GetOAuthParameters() {
        _parameters = new OAuth2Parameters {
            ClientId = ClientId,
            ClientSecret = CliendSecret,
            RedirectUri = RedirectUri,
            Scope = Scopes,
        };
    }

    private bool GetTokensFromMemory() {
        if (File.Exists("./tokens.txt")) {
            var lines = File.ReadLines("./tokens.txt").ToList();
            _accessToken = lines[0];
            _refreshToken = lines[1];
            return true;
        }
        _accessToken = _refreshToken = null;
        return false;
    }
}

有时候(有时不是,可能取决于非确定性参数),我会收到此异常:

Sometimes(and sometimes not,maybe depending on non-deterministic parameters) I get this exception:

System.Net.ProtocolViolationException : When performing a write operation with AllowWriteStreamBuffering set to false, you must either set ContentLength to a non-negative number or set SendChunked to true.
   at System.Net.HttpWebRequest.CheckProtocol(Boolean onRequestStream)
   at System.Net.HttpWebRequest.GetResponse()
   at Google.GData.Client.GDataRequest.Execute()
   at Google.GData.Client.GDataGAuthRequest.Execute(Int32 retryCounter)
   at Google.GData.Client.GOAuth2Request.Execute()
   at Google.GData.Client.Service.EntrySend(Uri feedUri, AtomBase baseEntry, GDataRequestType type, AsyncSendData data)
   at Google.GData.Client.Service.Insert(Uri feedUri, AtomEntry newEntry, AsyncSendData data)
   at Google.GData.Client.Service.Insert(Uri feedUri, TEntry entry)
   at Google.GData.Client.FeedRequest`1.Insert(Uri address, Y entry)
   at SomeDirectory.Tests.SomeClass.GoogleApiCallAddContact() in GmailApiLearningTests.cs: line 124

这似乎超出了我的代码范围,因为它深入到gdata的实现中.奇怪的是,当我在添加联系人时遇到此异常时,使用ContactRequest获取所有联系人的另一个测试也可以正常工作.有什么见解吗?

Which seems to be out of my code's scope, since it's deep within gdata's implementation. It's also strange that when I get this exception on adding a contact, an other test that uses a ContactRequest to get all contacts works just fine. Any insights on this?

更新:对于遇到相同问题的任何人,请执行以下操作:

Update: To anyone having the same issue do this:

try{
   cr.Insert(feedUri,newEntry);
}
catch(System.Net.ProtocolViolationException)
{
   cr.Insert(feedUri,newEntry);
}

问题是第一次插入失败(由于无效的访问令牌),客户端库调用OAuthUtil.RefreshAccessToken(parameters),但是以某种方式无法重新发出带有新令牌的插入,或者至少由于GDataRequestException而失败-> WebException,用于未授权.因此,通过执行上述操作,您可以刷新令牌并手动重新发出插入调用.

The problem is that the first insert fails(because of the invalid access token), the client lib calls OAuthUtil.RefreshAccessToken(parameters) but somehow fails to re-issue the insert with the new token or at least fail with a GDataRequestException->WebException for unauthorized. So by doing the above, you get your tokens refreshed and manually re-issue the insert call.

推荐答案

我遇到了相同的错误,问题是令牌已过期.您可以使用提琴手来确认.我遇到401错误.刷新令牌后,一切正常.希望有帮助.

I had the same error and the problem was that the token had expired. You can confirm that using fiddler. I had a 401 error. Once I refreshed the token, everything worked fine. Hope that help.

这篇关于ContactsRequest.Insert(feedUri,newEntry)有时会失败,并出现System.Net.ProtocolViolationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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