Google .NET API – 除FileDataStore之外的任何其他DataStore?

我正在使用Google .NET API从谷歌分析中获取分析数据。

这是我开始身份validation的代码:

IAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer { ClientSecrets = new ClientSecrets { ClientId = googleApiClientId, ClientSecret = googleApiClientSecret }, Scopes = new[] { Google.Apis.Analytics.v3.AnalyticsService.Scope.AnalyticsReadonly }, DataStore = new Google.Apis.Util.Store.FileDataStore("Test_GoogleApi") }); 

它使用FileDataStore作为文件存储在本地用户配置文件中。 我在ASP.NET应用程序中运行此代码,因此我无法真正使用该FileDataStore,因此我需要的是另一种获取数据的方法。

Google.Apis.Util.Store仅包含FileDataStore和IDataStore的接口。 在我开始实现自己的DataStore之前 – 是否还有其他可供下载的DataStore对象?

谢谢

Google的FileDataStore源代码可在此处获取 。

我已经编写了一个IDataStore的简单entity framework(版本6)实现,如下所示。

如果您希望将其放在单独的项目中,以及EF,则需要安装Google.Apis.Core nuget软件包。

 public class Item { [Key] [MaxLength(100)] public string Key { get; set; } [MaxLength(500)] public string Value { get; set; } } public class GoogleAuthContext : DbContext { public DbSet Items { get; set; } } public class EFDataStore : IDataStore { public async Task ClearAsync() { using (var context = new GoogleAuthContext()) { var objectContext = ((IObjectContextAdapter)context).ObjectContext; await objectContext.ExecuteStoreCommandAsync("TRUNCATE TABLE [Items]"); } } public async Task DeleteAsync(string key) { if (string.IsNullOrEmpty(key)) { throw new ArgumentException("Key MUST have a value"); } using (var context = new GoogleAuthContext()) { var generatedKey = GenerateStoredKey(key, typeof(T)); var item = context.Items.FirstOrDefault(x => x.Key == generatedKey); if (item != null) { context.Items.Remove(item); await context.SaveChangesAsync(); } } } public Task GetAsync(string key) { if (string.IsNullOrEmpty(key)) { throw new ArgumentException("Key MUST have a value"); } using (var context = new GoogleAuthContext()) { var generatedKey = GenerateStoredKey(key, typeof(T)); var item = context.Items.FirstOrDefault(x => x.Key == generatedKey); T value = item == null ? default(T) : JsonConvert.DeserializeObject(item.Value); return Task.FromResult(value); } } public async Task StoreAsync(string key, T value) { if (string.IsNullOrEmpty(key)) { throw new ArgumentException("Key MUST have a value"); } using (var context = new GoogleAuthContext()) { var generatedKey = GenerateStoredKey(key, typeof (T)); string json = JsonConvert.SerializeObject(value); var item = await context.Items.SingleOrDefaultAsync(x => x.Key == generatedKey); if (item == null) { context.Items.Add(new Item { Key = generatedKey, Value = json}); } else { item.Value = json; } await context.SaveChangesAsync(); } } private static string GenerateStoredKey(string key, Type t) { return string.Format("{0}-{1}", t.FullName, key); } } 

我知道这个问题已经回答了一段时间,但我认为这是一个很好的地方,可以分享我的发现,因为那些有类似困难的人找到了例子。 我发现使用桌面或MVC Web应用程序的Google API .Net库很难找到文档/示例。 我终于在你可以在Google Project网站上的示例存储库中找到的任务示例中找到了一个很好的例子< - 这真的对我帮助很大。

我最终窃取了FileDataStore的源代码并创建了一个AppDataStore类并将其放在我的App_Code文件夹中。 你可以在这里找到源代码,虽然它确实是一个简单的改变 – 改变文件夹指向〜/ App_Data。

我正在研究的最后一块拼图是获取offline_access令牌。


编辑:这是为方便起见的代码:

 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.IO; using System.Threading; using System.Threading.Tasks; using Google.Apis.Util.Store; using Google.Apis.Json; namespace Google.Apis.Util.Store { public class AppDataFileStore : IDataStore { readonly string folderPath; /// Gets the full folder path. public string FolderPath { get { return folderPath; } } ///  /// Constructs a new file data store with the specified folder. This folder is created (if it doesn't exist /// yet) under . ///  /// Folder name. public AppDataFileStore(string folder) { folderPath = Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/"), folder); if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } } ///  /// Stores the given value for the given key. It creates a new file (named ) in /// . ///  /// The type to store in the data store. /// The key. /// The value to store in the data store. public Task StoreAsync(string key, T value) { if (string.IsNullOrEmpty(key)) { throw new ArgumentException("Key MUST have a value"); } var serialized = NewtonsoftJsonSerializer.Instance.Serialize(value); var filePath = Path.Combine(folderPath, GenerateStoredKey(key, typeof(T))); File.WriteAllText(filePath, serialized); return TaskEx.Delay(0); } ///  /// Deletes the given key. It deletes the  named file in /// . ///  /// The key to delete from the data store. public Task DeleteAsync(string key) { if (string.IsNullOrEmpty(key)) { throw new ArgumentException("Key MUST have a value"); } var filePath = Path.Combine(folderPath, GenerateStoredKey(key, typeof(T))); if (File.Exists(filePath)) { File.Delete(filePath); } return TaskEx.Delay(0); } ///  /// Returns the stored value for the given key or null if the matching file ( /// in  doesn't exist. ///  /// The type to retrieve. /// The key to retrieve from the data store. /// The stored object. public Task GetAsync(string key) { if (string.IsNullOrEmpty(key)) { throw new ArgumentException("Key MUST have a value"); } TaskCompletionSource tcs = new TaskCompletionSource(); var filePath = Path.Combine(folderPath, GenerateStoredKey(key, typeof(T))); if (File.Exists(filePath)) { try { var obj = File.ReadAllText(filePath); tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize(obj)); } catch (Exception ex) { tcs.SetException(ex); } } else { tcs.SetResult(default(T)); } return tcs.Task; } ///  /// Clears all values in the data store. This method deletes all files in . ///  public Task ClearAsync() { if (Directory.Exists(folderPath)) { Directory.Delete(folderPath, true); Directory.CreateDirectory(folderPath); } return TaskEx.Delay(0); } /// Creates a unique stored key based on the key and the class type. /// The object key. /// The type to store or retrieve. public static string GenerateStoredKey(string key, Type t) { return string.Format("{0}-{1}", t.FullName, key); } } } 

我必须设置强制批准提示才能获得脱机访问令牌。

 var req = HttpContext.Current.Request; var oAuthUrl = Flow.CreateAuthorizationCodeRequest(new UriBuilder(req.Url.Scheme, req.Url.Host, req.Url.Port, GoogleCalendarUtil.CallbackUrl).Uri.ToString()) as GoogleAuthorizationCodeRequestUrl; oAuthUrl.Scope = string.Join(" ", new[] { CalendarService.Scope.CalendarReadonly }); oAuthUrl.ApprovalPrompt = "force"; oAuthUrl.State = AuthState; 

您基本上需要创建自己对Idatastore的限制,然后使用它。

 IDataStore StoredRefreshToken = new myDataStore(); // Oauth2 Autentication. using (var stream = new System.IO.FileStream("client_secret.json", System.IO.FileMode.Open, System.IO.FileAccess.Read)) { credential = GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(stream).Secrets, new[] { AnalyticsService.Scope.AnalyticsReadonly }, "user", CancellationToken.None, StoredRefreshToken).Result; } 

点击此处查看Idatastore的一个基本示例。 Google Oauth加载存储的刷新令牌

更新:

我的身份validation示例项目可以在GitHub上找到几个版本的Google-Dotnet-Samples / Authentication / Diamto.Google.Authentication

这里有Windows 8应用程序和Windows Phone的实现:

  • WP数据存储
  • WinRT数据存储

看一下以下线程将ASP.NET部署到Windows Azure云,在您要实现自己的DataStore之前,应用程序在云上运行时会出错 。

将来我们可能还有一个EF DataStore。 请记住,这是一个开源项目,因此您可以实施它并将其发送给审查:)请查看我们的贡献页面( https://code.google.com/p/google-api-dotnet-client/wiki/BecomingAContributor

我们的Web应用程序托管在Azure上,因此我需要为此创建一个IDataStore。

我使用Azure Table Storage作为我们的数据存储。

这是我尝试的要点

欢迎提供反馈和建议