2014-05-22 32 views
2

我有這樣一段代碼,用於將在測試Gmail帳戶的接觸我創建:ContactsRequest.Insert(feedUri,newEntry)有時會失敗,System.Net.ProtocolViolationException

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 = "[email protected]" 
     }); 


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

有時(有時不是,也許這取決於非確定性參數)我得到這個異常:

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獲取所有聯繫人的其他測試工作得很好。對此有何見解?


更新:具有相同問題的人做到這一點:

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

的問題是,第一插入失敗(因爲無效的訪問令牌),LIB調用OAuthUtil客戶端。 RefreshAccessToken(參數)但以某種方式無法重新發布帶有新令牌的插入,或者至少未通過GDataRequestException-> WebException未授權。因此,通過執行上述操作,您可以刷新令牌並手動重新發出插入調用。

回答

3

我有同樣的錯誤,問題是令牌已過期。你可以確認使用提琴手。我有一個401錯誤。一旦我刷新了令牌,一切正常。希望有所幫助。

+0

看來你是對的。儘管奇怪的是訪問令牌被自動刷新(就像在所有請求中一樣),但contactsRequest.Insert拋出,而不是像GetContacts()或Retrieve那樣使用新的訪問令牌。再次感謝。 – kaiseroskilo