web-dev-qa-db-fra.com

API Google .NET - tout autre magasin de données autre que le FileDataStore?

J'utilise l'API Google .NET pour obtenir des données d'analyse à partir de Google Analytics.

c'est moi le code pour commencer l'authentification:

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

il utilise le FileDataStore qui le stocke dans un profil d’utilisateur local sous forme de fichier. J'exécute ce code dans une application ASP.NET, je ne peux donc pas vraiment utiliser FileDataStore. Il me faut donc un autre moyen d'obtenir les données.

Google.Apis.Util.Store contient uniquement le FileDataStore et une interface de IDataStore. Avant d’implémenter mon propre stock de données, existe-t-il d’autres objets de stock de données disponibles pour le téléchargement?

Merci

23
developer82

La source de FileDataStore de Google est disponible ici .

J'ai écrit une implémentation simple d'IDataStore dans Entity Framework (version 6), comme illustré ci-dessous.

Si vous souhaitez insérer cela dans un projet séparé, ainsi que dans EF, vous aurez besoin du package 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<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);
    }
}
30
Simon Ness

Je sais que cette question a reçu une réponse il y a quelque temps, mais je pensais que ce serait un bon endroit pour partager mes conclusions pour ceux qui ont des difficultés similaires à trouver des exemples. J'ai trouvé difficile de trouver de la documentation/des exemples d'utilisation de la bibliothèque .Net de Google APIs pour une application Web Desktop ou MVC. J'ai enfin trouvé un bon exemple dans les exemples de tâches que vous pouvez trouver dans le référentiel d'exemples du site de projets Google ici <- Cela vraiment vraiment m'a aidé.

J'ai fini par accrocher le code source de FileDataStore et créé une classe AppDataStore que je plaçais dans mon dossier App_Code. Vous pouvez trouver la source ici , bien que ce soit un simple changement - changer le dossier pour qu'il pointe vers ~/App_Data à la place.

La dernière pièce du puzzle sur laquelle je cherche à trouver consiste à obtenir le jeton offline_access.


Edit: Voici le code pour plus de commodité:

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

Je devais définir l'invite d'approbation pour forcer afin d'obtenir le jeton d'accès hors connexion.

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;
5
Micah

Vous devez fondamentalement créer votre propre implication d'Idatastore, puis l'utiliser. 

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

Vérifiez ici pour un exemple de base d'une implimitation d'Idatastore. Google Oauth chargement du jeton d'actualisation stocké

Mettre à jour:

Vous trouverez plusieurs versions de cela dans l'exemple de projet d'authentification sur GitHub Google-Dotnet-Samples/Authentication/Diamto.Google.Authentication

2
DaImTo

Des implémentations pour les applications Windows 8 et Windows Phone sont disponibles ici:

Jetez un coup d'œil au fil suivant Déploiement d'ASP.NET sur un nuage Windows Azure, l'application génère une erreur lors de son exécution sur un nuage avant de mettre en œuvre votre propre stock de données.

À l'avenir, nous pourrions également avoir un stock de données EF. N'oubliez pas qu'il s'agit d'un projet open source, vous pouvez donc le mettre en œuvre et l'envoyer à l'examen :) Consultez notre page de contribution ( https://code.google.com/p/google-api-dotnet-client/wiki/Devenir un contributeur )

1
peleyal

Notre application Web étant hébergée sur Azure, je devais créer un IDataStore pour cela.

J'ai utilisé Azure Table Storage en tant que notre magasin de données.

Voici un résumé de ma tentative

Vos commentaires et suggestions sont les bienvenus

0
Eilimint