2014-12-02 60 views
9

我實現我的自定義IDataStore,這樣我可以存儲在我的數據庫,而不是默認的實現,這是保存在%APPDATA%以內文件系統最終用戶令牌谷歌雲端硬盤API - 自定義IDataStore實體框架

public class GoogleIDataStore : IDataStore 
{ 
    ... 

    public Task<T> GetAsync<T>(string key) 
    { 
     TaskCompletionSource<T> tcs = new TaskCompletionSource<T>(); 

     var user = repository.GetUser(key.Replace("oauth_", "")); 

     var credentials = repository.GetCredentials(user.UserId); 

     if (key.StartsWith("oauth") || credentials == null) 
     { 
      tcs.SetResult(default(T)); 
     } 
     else 
     { 
      var JsonData = Newtonsoft.Json.JsonConvert.SerializeObject(Map(credentials));     
      tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(JsonData)); 
     } 
     return tcs.Task; 
    } 
} 

控制器

public async Task<ActionResult> AuthorizeDrive(CancellationToken cancellationToken) 
{ 
    var result = await new AuthorizationCodeMvcApp(this, new GoogleAppFlowMetadata()). 
      AuthorizeAsync(cancellationToken); 

    if (result.Credential == null) 
     return new RedirectResult(result.RedirectUri); 

    var driveService = new DriveService(new BaseClientService.Initializer 
    { 
     HttpClientInitializer = result.Credential, 
     ApplicationName = "My app" 
    }); 

    //Example how to access drive files 
    var listReq = driveService.Files.List(); 
    listReq.Fields = "items/title,items/id,items/createdDate,items/downloadUrl,items/exportLinks"; 
    var list = listReq.Execute(); 

    return RedirectToAction("Index", "Home"); 
} 

問題發生在重定向事件。之後,第一次重定向它工作正常。

我發現重定向事件有些不同。在重定向事件上,T不是令牌響應,而是字符串。此外,密鑰前綴爲「oauth_」。

所以我認爲我應該返回一個不同的重定向結果,但我不知道該返回什麼。

我得到的錯誤是:Google.Apis.Auth.OAuth2.Responses.TokenResponseException:錯誤: 「國家是無效的」,說明: 「」 烏里: 「」

谷歌源代碼參考 https://code.google.com/p/google-api-dotnet-client/source/browse/Src/GoogleApis.DotNet4/Apis/Util/Store/FileDataStore.cs?r=eb702f917c0e18fc960d077af132d0d83bcd6a88

https://code.google.com/p/google-api-dotnet-client/source/browse/Src/GoogleApis.Auth/OAuth2/Web/AuthWebUtility.cs?r=eb702f917c0e18fc960d077af132d0d83bcd6a88

感謝您的幫助

回答

0

我不完全確定你爲什麼不工作,但這是我使用的代碼的副本。滿級都可以在這裏DatabaseDatastore.cs

/// <summary> 
     /// Returns the stored value for the given key or <c>null</c> if the matching file (<see cref="GenerateStoredKey"/> 
     /// in <see cref="FolderPath"/> doesn't exist. 
     /// </summary> 
     /// <typeparam name="T">The type to retrieve</typeparam> 
     /// <param name="key">The key to retrieve from the data store</param> 
     /// <returns>The stored object</returns> 
     public Task<T> GetAsync<T>(string key) 
     { 
      //Key is the user string sent with AuthorizeAsync 
      if (string.IsNullOrEmpty(key)) 
      { 
       throw new ArgumentException("Key MUST have a value"); 
      } 
      TaskCompletionSource<T> tcs = new TaskCompletionSource<T>(); 


      // Note: create a method for opening the connection. 
      SqlConnection myConnection = new SqlConnection("user id=" + LoginName + ";" + 
             @"password=" + PassWord + ";server=" + ServerName + ";" + 
             "Trusted_Connection=yes;" + 
             "database=" + DatabaseName + "; " + 
             "connection timeout=30"); 
      myConnection.Open(); 

      // Try and find the Row in the DB. 
      using (SqlCommand command = new SqlCommand("select RefreshToken from GoogleUser where UserName = @username;", myConnection)) 
      { 
       command.Parameters.AddWithValue("@username", key); 

       string RefreshToken = null; 
       SqlDataReader myReader = command.ExecuteReader(); 
       while (myReader.Read()) 
       { 
        RefreshToken = myReader["RefreshToken"].ToString(); 
       } 

       if (RefreshToken == null) 
       { 
        // we don't have a record so we request it of the user. 
        tcs.SetResult(default(T)); 
       } 
       else 
       { 

        try 
        { 
         // we have it we use that. 
         tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(RefreshToken)); 
        } 
        catch (Exception ex) 
        { 
         tcs.SetException(ex); 
        } 

       } 
      } 

      return tcs.Task; 
     } 
+0

嗨。 Mine也在工作。但是,在「StoreAsync」之後的初始重定向(用於授權訪問其谷歌驅動器)中,調用GetAsync並且鍵值爲*[email protected]*。所以這是我得到的錯誤。我不確定你的項目是否與我一樣是MVC ......這個問題可能與此有關。我將用「Controller」代碼編輯我的問題。 – 2014-12-06 14:59:36

0

的API存儲(至少)兩個值,發現您的IDataStore。以下是授權過程看起來像一個空IDataStore的觀點(注意這行設置一個值,該行得到值):

Getting IDataStore value: MyKey  <= null 

Setting IDataStore value: oauth_MyKey => "http://localhost..." 
Setting IDataStore value: MyKey  => {"access_token":"... 

Getting IDataStore value: oauth_MyKey <= "http://localhost..." 
Getting IDataStore value: MyKey  <= {"access_token":"... 

起初,API試圖找到一個存儲爲access_token,但數據存儲中沒有(僅返回null),API開始授權過程。 「oauth _...」鍵是API在此過程中需要的一些狀態信息,通常在檢索之前設置(根據我的經驗)。

但是,如果您的IDataStore從未收到帶有「oauth_ ..」鍵的值,並因此沒有任何返回值,則只需返回null,API將在需要時創建一個新值。