2013-12-10 2 views
21

Я использую API Google .NET для получения аналитических данных из Google Analytics.API Google .NET - любой другой DataStore, отличный от FileDataStore?

это мне код, чтобы начать проверку подлинности:

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, доступные для загрузки?

Благодаря

ответ

1

Там являются реализациями для ОС Windows 8 приложений и Windows Phone доступен здесь:

Взгляните на следующую нить Deploying ASP.NET to Windows Azure cloud, application gives error when running on cloud, прежде чем вы собирается реализовать собственный DataStore.

В будущем у нас также может быть EF DataStore. Помните, что это проект с открытым исходным кодом, поэтому вы можете его реализовать и отправить его на рассмотрение :) Взгляните на нашу страницу вклада (https://code.google.com/p/google-api-dotnet-client/wiki/BecomingAContributor)

+0

спасибо! – Nozdrum

2

Вам в основном необходимо создать собственное импликацию 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; 
} 

Отметьте здесь базовый пример импликации Идастастора. Google Oauth loading stored refresh token

Update:

несколько версий этого можно найти в моем примере проекта аутентификации на GitHub Google-Dotnet-Samples/Authentication/Diamto.Google.Authentication

28

Источником FileDataStore Google доступен here.

Я написал простую реализацию Entity Framework (версия 6) IDataStore, как показано ниже.

Если вы хотите разместить это в отдельном проекте, а также EF, вам понадобится пакет nuget Google.Apis.Core.

public class Item 
{ 
    [Key] 
    [MaxLength(100)] 
    public string Key { get; set; } 

    [MaxLength(500)] 
    public string Value { get; set; } 
} 

public class GoogleAuthContext : DbContext 
{ 
    public DbSet<Item> 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<T>(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<T> GetAsync<T>(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<T>(item.Value); 
      return Task.FromResult<T>(value); 
     } 
    } 

    public async Task StoreAsync<T>(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); 
    } 
} 
+2

работает как очарование! Благодаря! –

+0

Как я могу использовать этот efdatastore? –

+0

Работает на локальной машине, но я получил «Формат строки инициализации не соответствует спецификации, начинающейся с индекса 0» на Azure – Kirill

5

Я знаю, что этот вопрос был дан ответ некоторое время назад, но я думал, что это было бы хорошее место, чтобы поделиться своими выводами для тех, кто имеет аналогичные трудности в поиске примеров. Я обнаружил, что трудно найти документацию/образцы при использовании библиотеки API. API для веб-приложения Desktop или MVC. Наконец, я нашел хороший пример в примере задач, который вы можете найти в репозитории образцов на сайте Google Project. here < - Это действительно действительно помогло мне.

Я закончил тем, что зацепил источник для FileDataStore и создал класс AppDataStore и поместил его в папку App_Code. Вы можете найти источник here, хотя это было простое изменение - изменение папки, чтобы указать на ~/App_Data.

Последний кусочек головоломки, которую я ищу в поиске, получает токен offline_access.


Edit: Вот код для удобства:

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; 
     /// <summary>Gets the full folder path.</summary> 
     public string FolderPath { get { return folderPath; } } 

     /// <summary> 
     /// Constructs a new file data store with the specified folder. This folder is created (if it doesn't exist 
     /// yet) under <see cref="Environment.SpecialFolder.ApplicationData"/>. 
     /// </summary> 
     /// <param name="folder">Folder name.</param> 
     public AppDataFileStore(string folder) { 
      folderPath = Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/"), folder); 
      if (!Directory.Exists(folderPath)) { 
       Directory.CreateDirectory(folderPath); 
      } 
     } 

     /// <summary> 
     /// Stores the given value for the given key. It creates a new file (named <see cref="GenerateStoredKey"/>) in 
     /// <see cref="FolderPath"/>. 
     /// </summary> 
     /// <typeparam name="T">The type to store in the data store.</typeparam> 
     /// <param name="key">The key.</param> 
     /// <param name="value">The value to store in the data store.</param> 
     public Task StoreAsync<T>(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); 
     } 

     /// <summary> 
     /// Deletes the given key. It deletes the <see cref="GenerateStoredKey"/> named file in 
     /// <see cref="FolderPath"/>. 
     /// </summary> 
     /// <param name="key">The key to delete from the data store.</param> 
     public Task DeleteAsync<T>(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); 
     } 

     /// <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) { 
      if (string.IsNullOrEmpty(key)) { 
       throw new ArgumentException("Key MUST have a value"); 
      } 

      TaskCompletionSource<T> tcs = new TaskCompletionSource<T>(); 
      var filePath = Path.Combine(folderPath, GenerateStoredKey(key, typeof(T))); 
      if (File.Exists(filePath)) { 
       try { 
        var obj = File.ReadAllText(filePath); 
        tcs.SetResult(NewtonsoftJsonSerializer.Instance.Deserialize<T>(obj)); 
       } 
       catch (Exception ex) { 
        tcs.SetException(ex); 
       } 
      } 
      else { 
       tcs.SetResult(default(T)); 
      } 
      return tcs.Task; 
     } 

     /// <summary> 
     /// Clears all values in the data store. This method deletes all files in <see cref="FolderPath"/>. 
     /// </summary> 
     public Task ClearAsync() { 
      if (Directory.Exists(folderPath)) { 
       Directory.Delete(folderPath, true); 
       Directory.CreateDirectory(folderPath); 
      } 

      return TaskEx.Delay(0); 
     } 

     /// <summary>Creates a unique stored key based on the key and the class type.</summary> 
     /// <param name="key">The object key.</param> 
     /// <param name="t">The type to store or retrieve.</param> 
     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; 
+0

Вы разработали токен offline_access? – Craig

+0

Извините за задержку Крейга, да, на самом деле я выяснил токен offline_access. Я должен был добавить: oAuthUrl.ApprovalPrompt = "force"; – Micah

+0

Спасибо, Мика. В конце концов мне удалось все это работать. – Craig

Смежные вопросы