webentwicklung-frage-antwort-db.com.de

Google .NET-APIs - ein anderer DataStore als der FileDataStore?

Ich verwende die Google .NET-API, um Analysedaten von Google Analytics abzurufen.

dies ist mein Code, um die Authentifizierung zu starten:

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

es verwendet den FileDataStore, der im lokalen Benutzerprofil als Datei gespeichert ist. Ich führe diesen Code in einer ASP.NET-Anwendung aus, sodass ich diesen FileDataStore nicht wirklich verwenden kann. Ich benötige also eine andere Möglichkeit, um die Daten abzurufen.

Google.Apis.Util.Store enthält nur den FileDataStore und eine Schnittstelle von IDataStore. Gibt es noch andere DataStore-Objekte zum Herunterladen, bevor ich meinen eigenen DataStore implementiere?

Vielen Dank

23
developer82

Die Quelle für Googles FileDataStore ist verfügbar hier .

Ich habe eine einfache Implementierung von IDataStore in Entity Framework (Version 6) geschrieben, wie unten gezeigt.

Wenn Sie dies in einem separaten Projekt und in EF zusammenstellen möchten, muss das Paket Google.Apis.Core nuget installiert sein.

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

Ich weiß, dass diese Frage vor einiger Zeit beantwortet wurde, aber ich dachte, dies wäre ein guter Ort, um meine Ergebnisse für diejenigen mit ähnlichen Schwierigkeiten auszutauschen, die Beispiele finden. Ich habe festgestellt, dass es schwierig ist, Dokumentation/Beispiele zur Verwendung der Google APIs .Net-Bibliothek für eine Desktop- oder MVC-Webanwendung zu finden. Ich habe endlich ein gutes Beispiel in dem Aufgabenbeispiel gefunden, das Sie im Beispiel-Repository auf der Google Project-Website finden können. hier <- Das wirklich wirklich hat mir geholfen.

Am Ende habe ich die Quelle für den FileDataStore erstellt und eine AppDataStore-Klasse erstellt und in meinem App_Code-Ordner abgelegt. Sie finden die Quelle hier , obwohl es wirklich eine einfache Änderung war - ändern Sie den Ordner stattdessen in ~/App_Data.

Das letzte Stück des Puzzles, das ich mir anschaue, ist das offline_access-Token.


Edit: Hier ist der Code für die Bequemlichkeit:

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

Ich musste die Erlaubnisaufforderung festlegen, um das Offline-Zugriffstoken zu erzwingen.

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

Sie müssen grundsätzlich Ihre eigene Implementierung von Idatastore erstellen und diese dann verwenden. 

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

Hier finden Sie ein einfaches Beispiel für eine Implementierung von Idatastore. Google Oauth lädt gespeicherte Aktualisierungstoken

Update:

Einige Versionen davon finden Sie in meinem Authentication-Beispielprojekt auf GitHub Google-Dotnet-Samples/Authentication/Diamto.Google.Authentication

2
DaImTo

Es gibt Implementierungen für Windows 8-Anwendungen und Windows Phone hier:

Werfen Sie einen Blick in den folgenden Thread Beim Bereitstellen von ASP.NET in der Windows Azure-Cloud gibt die Anwendung bei der Ausführung in der Cloud einen Fehler aus , bevor Sie Ihren eigenen DataStore implementieren.

In Zukunft könnten wir auch einen EF DataStore haben. Denken Sie daran, dass es sich um ein Open-Source-Projekt handelt, das Sie implementieren und zur Überprüfung senden können. Schauen Sie sich unsere Beitragsseite an ( https://code.google.com/p/google-api-dotnet-client/ wiki/BecomingAContributor )

1
peleyal

Unsere Web-App wird auf Azure gehostet. Daher musste ich einen IDataStore erstellen.

Ich habe Azure Table Storage als Datenspeicher verwendet.

Hier ist ein Gist meines Versuchs

Feedback und Vorschläge sind willkommen

0
Eilimint