André Alves de Lima

Talking about Software Development and more…

Utilizando a API do Google Drive no C# e VB.NET

Hoje em dia é muito difícil encontrar algum aplicativo que não salve algum tipo de informação na nuvem. Com serviços como Dropbox, Google Drive e OneDrive ficando cada vez mais baratos e acessíveis, a nossa vida acaba sendo muito facilitada caso precisemos subir um arquivo para a nuvem a partir da nossa aplicação.

Para facilitar ainda mais a nossa vida, esses serviços sempre contam com APIs que podem ser acessadas nas mais diversas plataformas de desenvolvimento. O Google Drive, por exemplo, conta com uma API bem extensa, possibilitando a manipulação completa dos seus serviços a partir de aplicações de terceiros.

No artigo de hoje eu vou mostrar para você como fazer todo tipo de interação com o Google Drive no C# e VB.NET. Primeiramente nós veremos como habilitar a API do Google Drive na nossa conta e como gerar o arquivo de credenciais que é necessário para o seu acesso. Em seguida, nós aprenderemos todas as operações que podemos executar com a API: listagem, criação, exclusão e download de arquivos.

A API do Google Drive

O Google Drive conta com uma extensa API que possibilita a manipulação do conteúdo das suas contas em projetos que utilizem qualquer linguagem de programação com suporte a serviços REST. No momento da escrita deste artigo, a API está na sua terceira versão.

Se procurarmos na Internet por exemplos da manipulação do Google Drive com .NET, encontraremos uma boa quantidade de artigos que utilizam a segunda versão da API (como essa excelente série que eu utilizei de inspiração para escrever este artigo). Porém, se quisermos utilizar a versão mais nova da API (que já foi lançada há um bom tempo, no final de 2015), acabamos ficando na mão. Existem diversas diferenças entre a versão 2 e a versão 3 da API, que estão todas documentadas aqui.

A própria página da API conta com alguns exemplos em C# (como, por exemplo, este quickstart). Porém, esses exemplos são muito simples e com pouca explicação do que está sendo feito em cada etapa. Além disso, eles estão todos quebrados em funcionalidades, ou seja, nós não conseguimos encontrar um exemplo que aborde todas as principais interações que podemos fazer com o Google Drive através da nossa aplicação. Neste artigo eu vou juntar todas essas informações em um só lugar e vou explicar para você o que está sendo feito em cada etapa.

Gerando o arquivo com as credenciais

Antes de tentarmos desenvolver qualquer funcionalidade na nossa aplicação utilizando a API do Google Drive, nós precisamos habilitar o suporte à API na nossa conta e temos que gerar também um arquivo com as nossas credenciais. Se você ainda não tiver seguido esses passos com a sua conta, este é o link para o assistente.

O primeiro passo é muito simples. Nós só temos que concordar com os termos do serviço (obviamente, nós não temos outra escolha):

Ao concordarmos com os termos, a API será ativada na nossa conta e nós conseguiremos continuar com o próximo passo, que é a criação do nosso arquivo de credenciais:

Na próxima etapa, escolha a API do Google Drive e a opção “Other UI“, uma vez que nós criaremos uma aplicação console Windows:

Em seguida, nós temos a possibilidade de fazer uma configuração muito interessante para o arquivo de credenciais, que basicamente responde à seguinte pergunta: esse arquivo de credenciais dará acesso a todos os arquivos e pastas do Google Drive ou somente a arquivos e pastas gerados por essa aplicação específica? Escolha a opção que melhor se enquadra no cenário da sua aplicação e prossiga para a próxima etapa. No meu caso, eu escolhi a opção “User data“, que dá acesso a todos os arquivos e pastas da conta:

Edit: o James Maxwel me corrigiu nos comentários quanto à questão dos tipos de credenciais. Segue aqui a explicação dele: “A primeira [opção] “User Data” é necessária quando sua aplicação necessita gerenciar os arquivos do usuário, isto exige o consentimento do mesmo. Já a segunda [opção] “Application Data” é necessária quando sua aplicação gerencia sua própria conta no drive e para isto não necessita do consentimento do usuário tendo em vista que você já possui estes dados”. Obrigado pela correção, James!

Agora chegou a hora de escolher um nome para o Client ID e produto. Além disso, caso a sua conta esteja conectada com outras contas do Google, você terá que selecionar o e-mail da conta que você quer utilizar:

Pronto! Finalmente chegamos na última etapa do assistente, onde conseguimos fazer o download do arquivo com as credenciais. Clique no botão “Download” e salve o arquivo “client_id.json” em um local que seja acessível pela aplicação:

Adicionando a referência da API no projeto

Para a nossa sorte, a própria Google implementou um conjunto de classes “helpers” em .NET que fazem o encapsulamento das chamadas da API de maneira mais amigável. Se essas classes não existissem, nós teríamos que fazer as chamadas manualmente através de requisições HTTP.

Esse conjunto de classes está publicado no NuGet com o nome “Google.Apis.Drive.v3“, ou seja, para adicionar a referência no nosso projeto basta procurarmos por esse termo na janela “NuGet Package Manager” ou podemos executar também o comando “Install-Package Google.Apis.Drive.v3” no “Package Manager Console“:

Para facilitar a nossa vida, os exemplos desse artigo serão construídos em um projeto do tipo “Console Application“. Porém, nada impede que você aplique os mesmos conceitos em outros tipos de projeto, como Windows Forms, WPF ou ASP.NET.

Autenticando e conectando no serviço

A primeira coisa que temos que fazer antes de acessarmos a API do Google Drive é nos autenticarmos utilizando aquele arquivo que geramos nas etapas anteriores. Dito isso, vamos criar um método que retornará uma instância da classe “UserCredential” da API do Google Drive. Esse método fará toda a “mágica” da autenticação sempre que precisarmos nos conectar na API.

Dentro desse método nós precisaremos informar três parâmetros importantes: uma stream apontando para o arquivo com as credenciais (“client_id.json” que geramos anteriormente), o escopo das permissões que serão dadas para execução de comandos na API e o caminho para uma pasta onde será armazenado o token da autenticação. Esse token servirá como um “cache” das nossas credenciais, evitando que tenhamos que digitar o nosso usuário e senha novamente todas as vezes que o aplicativo for executado.

Veja como fica o código desse método:

        // C#
        private static Google.Apis.Auth.OAuth2.UserCredential Autenticar()
        {
            Google.Apis.Auth.OAuth2.UserCredential credenciais;

            using (var stream = new System.IO.FileStream("client_id.json", System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                var diretorioAtual = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                var diretorioCredenciais = System.IO.Path.Combine(diretorioAtual, "credential");

                credenciais = Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.AuthorizeAsync(
                    Google.Apis.Auth.OAuth2.GoogleClientSecrets.Load(stream).Secrets,
                    new[] { Google.Apis.Drive.v3.DriveService.Scope.DriveReadonly },
                    "user",
                    System.Threading.CancellationToken.None,
                    new Google.Apis.Util.Store.FileDataStore(diretorioCredenciais, true)).Result;
            }

            return credenciais;
        }
    ' VB.NET
    Private Function Autenticar() As Google.Apis.Auth.OAuth2.UserCredential
        Dim Credenciais As Google.Apis.Auth.OAuth2.UserCredential

        Using Stream = New System.IO.FileStream("client_id.json", System.IO.FileMode.Open, System.IO.FileAccess.Read)
            Dim DiretorioAtual = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
            Dim DiretorioCredenciais = System.IO.Path.Combine(DiretorioAtual, "credential")

            Credenciais = Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.AuthorizeAsync(
                Google.Apis.Auth.OAuth2.GoogleClientSecrets.Load(Stream).Secrets,
                New String() {Google.Apis.Drive.v3.DriveService.Scope.DriveReadonly},
                "user",
                System.Threading.CancellationToken.None,
                New Google.Apis.Util.Store.FileDataStore(DiretorioCredenciais, True)).Result
        End Using

        Return Credenciais
    End Function

À primeira vista esse código parece bem complicado. Porém, ele é mais simples do que parece. Primeiramente nós abrimos um FileStream somente leitura apontando para o arquivo “client_id.json“, que você terá que copiar para o diretório “bin/debug” do projeto. Em seguida, nós criamos uma variável que armazenará o caminho completo para um subdiretório da aplicação, chamado de “credential“. Esse é o diretório onde o token com as credenciais será armazenado. Por fim, nós fazemos a chamada ao método “GoogleWebAuthorizationBroker.AuthorizeAsync“, que deverá receber esses e outros parâmetros.

Note que a princípio estamos pedindo somente a permissão de leitura para a API (DriveReadonly). Ou seja, com essas permissões nós só conseguiremos listar as informações do nosso Google Drive. Mais para a frente nós veremos como essa permissão se comportará ao tentarmos escrever alguma alteração nos objetos da nossa conta.

Os parâmetros “user” e “CancellationToken.None” eu sinceramente não sei para que servem. Eu copiei essa chamada do exemplo oficial da própria Google e não consegui entender a utilidade desses parâmetros. Se alguém souber ou descobrir, avisa nos comentários.

Enfim, uma vez autenticado no serviço, nós temos que iniciar uma conexão. Para isso, nós temos que criar uma nova instância da classe “DriveService” passando um “Initializer” com as nossas credenciais. Entendeu? Pois é, eu sei que é complicado, então vamos ao código:

        // C#
        private static Google.Apis.Drive.v3.DriveService AbrirServico(Google.Apis.Auth.OAuth2.UserCredential credenciais)
        {
            return new Google.Apis.Drive.v3.DriveService(new Google.Apis.Services.BaseClientService.Initializer()
            {
                HttpClientInitializer = credenciais
            });
        }
    ' VB.NET
    Private Function AbrirServico(Credenciais As Google.Apis.Auth.OAuth2.UserCredential) As Google.Apis.Drive.v3.DriveService
        Return New Google.Apis.Drive.v3.DriveService(New Google.Apis.Services.BaseClientService.Initializer() With {
            .HttpClientInitializer = Credenciais
        })
    End Function

Bem mais simples do que quando eu tentei explicar, não é mesmo?

OK. Agora nós já temos o código que faz a autenticação e o código que abre uma conexão com a API do Google Drive. O próximo passo é implementar os métodos que farão a interação com o conteúdo do nosso repositório. Porém, qualquer interação que queiramos fazer com a API, nós precisaremos de uma instância da classe “DriveService” pronta para uso. Dessa forma, no local onde faremos as chamadas à API (por exemplo, o método “main” de um projeto console), nós criaremos um bloco “using” que fará a abertura do serviço:

            // C#
            var credenciais = Autenticar();

            using (var servico = AbrirServico(credenciais))
            {
            }
        ' VB.NET
        Dim Credenciais = Autenticar()

        Using Servico = AbrirServico(Credenciais)

        End Using

Como a classe “DriveService” implementa a interface “IDisposable“, ao colocarmos o código dentro de um bloco “using“, a conexão com a API será devidamente fechada e descartada assim que o bloco “using” for terminado, evitando que nós tenhamos que implementar código extra para fecharmos a conexão. Todo o código que fará a manipulação do nosso Google Drive deverá ser implementado dentro desse bloco “using“.

Listagem de arquivos

Com o serviço inicializado, vamos partir para a interação com os arquivos e pastas do nosso Google Drive. Primeiramente, vamos listar todo o conteúdo do nosso repositório?

Todos os métodos de interação do Google Drive estão implementados na propriedade “Files” da classe “DriveService“. Por exemplo, para criarmos um request que fará a listagem dos arquivos, nós teremos que chamar o método “servico.Files.List“. Essa mesma ideia servirá como base para os outros tipos de operações nas próximas seções deste artigo. Vamos ver como é que fica o código, dessa forma fica mais fácil de explicar:

        // C#
        private static void ListarArquivos(Google.Apis.Drive.v3.DriveService servico)
        {
            var request = servico.Files.List();
            request.Fields = "files(id, name)";
            var resultado = request.Execute();
            var arquivos = resultado.Files;

            if (arquivos != null && arquivos.Any())
            {
                foreach (var arquivo in arquivos)
                {
                    Console.WriteLine(arquivo.Name);
                }
            }
        }
    ' VB.NET
    Private Sub ListarArquivos(Servico As Google.Apis.Drive.v3.DriveService)
        Dim Request = Servico.Files.List()
        Request.Fields = "files(id, name)"
        Dim Resultado = Request.Execute()
        Dim Arquivos = Resultado.Files

        If Arquivos IsNot Nothing AndAlso Arquivos.Any() Then
            For Each Arquivo In Arquivos
                Console.WriteLine(Arquivo.Name)
            Next
        End If
    End Sub

Como você pode ver, primeiro nós criamos um request para o método de listagem de arquivos (“Files.List“). Em seguida, nós especificamos quais são os campos dos arquivos e pastas que devem ser retornados pelo request. Essa é uma grande diferença entre a segunda e a terceira versões da API. Pelo que eu entendi, na segunda versão, todos os campos eram retornados automaticamente. Já na terceira versão, nós precisamos especificar quais campos devem ser retornados, senão a API só retornará o ID dos arquivos e pastas.

Por fim, nós executamos o request e percorremos o resultado (que é uma lista de arquivos e pastas que estão armazenados no nosso Google Drive), imprimindo o nome dos itens. Vamos chamar esse método dentro do nosso bloco “using” para vermos o resultado:

                // C#
                Console.WriteLine("Listagem");
                ListarArquivos(servico);
                Console.WriteLine("Fim Listagem");
                Console.ReadLine();
            ' VB.NET
            Console.WriteLine("Listagem")
            ListarArquivos(Servico)
            Console.WriteLine("Fim Listagem")
            Console.ReadLine()

Aparentemente tudo funcionou perfeitamente, não é mesmo? Porém, essa metodologia só retornará os 100 primeiros itens que forem encontrados no nosso Google Drive. Se quisermos que mais itens sejam retornados, temos que alterar a propriedade “PageSize” do nosso request antes de executá-lo. Por exemplo:

            // C#
            request.PageSize = 1000;
            var resultado = request.Execute();
        ' VB.NET
        Request.PageSize = 1000
        Dim Resultado = Request.Execute()

O valor padrão dessa propriedade é “100“, e o máximo é “1000“. Se tentarmos utilizar um valor maior do que 1000, receberemos o seguinte erro:

Outro detalhe importante é que, por padrão, a listagem de arquivos também retorna todos os arquivos que estiverem na lixeira. Se esse não for o comportamento que você está querendo, basta configurar um filtro para o request, através da propriedade “Q“. Exemplo:

// C#
request.Q = "trashed=false";
' VB.NET
Request.Q = "trashed=false"

Listagem paginada

Como vimos na seção anterior, o máximo de arquivos e pastas que serão listados pela API do Google Drive é 1000. Mas, o que fazemos se quisermos listar mais do que 1000 itens? Nesse caso, a saída é fazer uma listagem paginada, ou seja, retornarmos “X” itens de cada vez.

Para fazermos isso, nós temos que retornar também o “nextPageToken” na hora de listarmos os itens. Com isso, sempre que executarmos o request, caso ainda existam itens para serem retornados, o resultado sempre contará com um token que possibilitará a listagem da próxima página. Veja como é que fica o código de um novo método para listagem de arquivos que receberá também a quantidade de itens por página:

        // C#
        private static void ListarArquivosPaginados(Google.Apis.Drive.v3.DriveService servico, int arquivosPorPagina)
        {
            var request = servico.Files.List();
            request.Fields = "nextPageToken, files(id, name)";
            //request.Q = "trashed=false";
            // Default 100, máximo 1000.
            request.PageSize = arquivosPorPagina;
            var resultado = request.Execute();
            var arquivos = resultado.Files;

            while (arquivos != null && arquivos.Any())
            {
                foreach (var arquivo in arquivos)
                {
                    Console.WriteLine(arquivo.Name);
                }

                if (resultado.NextPageToken != null)
                {
                    Console.WriteLine("Digite ENTER para ir para a próxima página");
                    Console.ReadLine();
                    request.PageToken = resultado.NextPageToken;
                    resultado = request.Execute();
                    arquivos = resultado.Files;
                }
                else
                {
                    arquivos = null;
                }
            }
        }
    ' VB.NET
    Private Sub ListarArquivosPaginados(Servico As Google.Apis.Drive.v3.DriveService, ArquivosPorPagina As Integer)
        Dim Request = Servico.Files.List()
        Request.Fields = "nextPageToken, files(id, name)"
        'Request.Q = "trashed=false"
        ' Default 100, máximo 1000.
        Request.PageSize = ArquivosPorPagina
        Dim Resultado = Request.Execute()
        Dim Arquivos = Resultado.Files

        While Arquivos IsNot Nothing AndAlso Arquivos.Any()
            For Each arquivo In Arquivos
                Console.WriteLine(arquivo.Name)
            Next

            If Resultado.NextPageToken IsNot Nothing Then
                Console.WriteLine("Digite ENTER para ir para a próxima página")
                Console.ReadLine()
                Request.PageToken = Resultado.NextPageToken
                Resultado = Request.Execute()
                Arquivos = Resultado.Files
            Else
                Arquivos = Nothing
            End If
        End While
    End Sub

No bloco “using“, nós podemos chamar esse novo método, passando a quantidade de itens por página. Por exemplo, o código para listarmos os itens de 10 em 10 ficaria assim:

                // C#
                Console.Clear();
                Console.WriteLine("Listagem paginada");
                ListarArquivosPaginados(servico, 10);
                Console.WriteLine("Fim Listagem paginada");
                Console.ReadLine();
            ' VB.NET
            Console.Clear()
            Console.WriteLine("Listagem paginada")
            ListarArquivosPaginados(Servico, 10)
            Console.WriteLine("Fim Listagem paginada")
            Console.ReadLine()

Veja só o resultado:

Criação de diretórios

Agora que já conseguimos listar os itens do nosso Google Drive, vamos conferir como é que podemos fazer para criarmos um novo diretório. Estranhamente, tudo no Google Drive são “itens“. Ou seja, arquivos e diretórios são ambos tratados como “File” (arquivo). A única diferença é que diretórios possuem um “mime type” específico, que fará com que o Google Drive entenda que ele é um diretório, e não um arquivo.

A criação do diretório é bem simples. Basta criarmos uma nova instância da classe “File” e configurarmos um nome e o “mime type” indicando que ele é um diretório. Em seguida, criamos e executamos um request utilizando o método “Files.Create” passando a instância de “File” que instanciamos anteriormente:

        // C#
        private static void CriarDiretorio(Google.Apis.Drive.v3.DriveService servico, string nomeDiretorio)
        {
            var diretorio = new Google.Apis.Drive.v3.Data.File();
            diretorio.Name = nomeDiretorio;
            diretorio.MimeType = "application/vnd.google-apps.folder";
            var request = servico.Files.Create(diretorio);
            request.Execute();
        }
    ' VB.NET
    Private Sub CriarDiretorio(Servico As Google.Apis.Drive.v3.DriveService, NomeDiretorio As String)
        Dim Diretorio = New Google.Apis.Drive.v3.Data.File()
        Diretorio.Name = NomeDiretorio
        Diretorio.MimeType = "application/vnd.google-apps.folder"
        Dim Request = Servico.Files.Create(Diretorio)
        Request.Execute()
    End Sub

Para criarmos um diretório chamado “NovoDiretorio” temos que fazer a seguinte chamada dentro do nosso bloco “using“:

                // C#
                Console.Clear();
                Console.WriteLine("Criar diretório");
                CriarDiretorio(servico, "NovoDiretorio");
                Console.WriteLine("Fim Criar diretório");
                Console.ReadLine();
            ' VB.NET
            Console.Clear()
            Console.WriteLine("Criar diretório")
            CriarDiretorio(Servico, "NovoDiretorio")
            Console.WriteLine("Fim Criar diretório")
            Console.ReadLine()

Porém, ao tentarmos executar esse código com o escopo de permissões que utilizamos anteriormente (“Scope.DriveReadonly“), nós receberemos um erro informando que não temos permissões suficientes:

Obviamente, o escopo “readonly” não permite a criação ou exclusão de itens. Se quisermos alterar itens no nosso Google Drive, teremos que alterar o escopo para “Scope.Drive” na hora de criarmos as credenciais (método “Autenticar“). Só não esqueça de deletar o subdiretório “credential” dentro da pasta “bin/debug“, uma vez que as credenciais com o escopo menor já estarão cacheadas nesse diretório e a autenticação continuará utilizando esse escopo “readonly” caso você não delete essa pasta para forçar uma nova autenticação.

Atenção! Um leitor do meu site (o Daniel Marques) disse que no teste que ele fez desse código no Windows Forms, ao utilizar o escopo “DriveReadonly”, a API não retornou nenhum erro. O upload simplesmente não funcionou, mas não acusou nenhum erro. Caso você esteja passando por uma situação semelhante, não esqueça de verificar se o escopo está corretamente configurado no seu método de autenticação!

Depois de seguir todos esses passos, ao executarmos novamente a aplicação, este será o resultado no nosso Google Drive:

Só tome cuidado, pois outra coisa estranha do Google Drive é que ele não liga para nomes repetidos. Ou seja, se você executar esse código duas vezes, ele criará duas vezes o mesmo diretório sem problema algum:

Deletando arquivos ou diretórios

A próxima operação que vamos conferir neste artigo é a exclusão de itens do nosso Google Drive. A exclusão em si é muito simples. Basta criarmos e executarmos um request para o método “Files.Delete” passando o “id” do item a ser deletado. A parte mais difícil está em descobrir o “id” do item que estamos querendo deletar.

Para descobrirmos o “id” de um item através do seu nome, nós temos que basicamente executar um comando de listagem filtrado, requisitando somente o “id” dos itens que tenham um nome específico. Vamos implementar primeiramente um método que retornará esses “ids“:

        // C#
        private static string[] ProcurarArquivoId(Google.Apis.Drive.v3.DriveService servico, string nome, bool procurarNaLixeira = false)
        {
            var retorno = new List<string>();

            var request = servico.Files.List();
            request.Q = string.Format("name = '{0}'", nome);
            if (!procurarNaLixeira)
            {
                request.Q += " and trashed = false";
            }
            request.Fields = "files(id)";
            var resultado = request.Execute();
            var arquivos = resultado.Files;

            if (arquivos != null && arquivos.Any())
            {
                foreach (var arquivo in arquivos)
                {
                    retorno.Add(arquivo.Id);
                }
            }

            return retorno.ToArray();
        }
    ' VB.NET
    Private Function ProcurarArquivoId(Servico As Google.Apis.Drive.v3.DriveService, Nome As String, Optional ProcurarNaLixeira As Boolean = False) As String()
        Dim Retorno = New List(Of String)()

        Dim Request = Servico.Files.List()
        Request.Q = String.Format("name = '{0}'", Nome)
        If Not ProcurarNaLixeira Then
            Request.Q += " and trashed = false"
        End If
        Request.Fields = "files(id)"
        Dim Resultado = Request.Execute()
        Dim Arquivos = Resultado.Files

        If Arquivos IsNot Nothing AndAlso Arquivos.Any() Then
            For Each Arquivo In Arquivos
                Retorno.Add(Arquivo.Id)
            Next
        End If

        Return Retorno.ToArray()
    End Function

Note que o método já está preparado para procurar itens na lixeira também. No nosso caso, nós não precisaremos dessa opção, mas já é bom implementá-la caso precisemos mais adiante.

Agora que já conseguimos uma lista com os “ids” dos itens, a exclusão fica muito simples:

        // C#
        private static void DeletarItem(Google.Apis.Drive.v3.DriveService servico, string nome)
        {
            var ids = ProcurarArquivoId(servico, nome);
            if (ids != null && ids.Any())
            {
                foreach (var id in ids)
                {
                    var request = servico.Files.Delete(id);
                    request.Execute();
                }
            }
        }
    ' VB.NET
    Private Sub DeletarItem(Servico As Google.Apis.Drive.v3.DriveService, Nome As String)
        Dim Ids = ProcurarArquivoId(Servico, Nome)
        If Ids IsNot Nothing AndAlso Ids.Any() Then
            For Each Id In Ids
                Dim Request = Servico.Files.Delete(Id)
                Request.Execute()
            Next
        End If
    End Sub

Por fim, a chamada para deletarmos o diretório “NovoDiretorio” que criamos anteriormente ficaria da seguinte maneira:

                // C#
                Console.Clear();
                Console.WriteLine("Deletar item");
                DeletarItem(servico, "NovoDiretorio");
                Console.WriteLine("Fim Deletar item");
                Console.ReadLine();
            ' VB.NET
            Console.Clear()
            Console.WriteLine("Deletar item")
            DeletarItem(Servico, "NovoDiretorio")
            Console.WriteLine("Fim Deletar item")
            Console.ReadLine()

Fazendo o upload de arquivos

O upload de arquivos no Google Drive parece ser bem tranquilo à primeira vista. Temos à nossa disposição o método “Files.Create” que recebe uma instância de “File” (com as informações de nome e tipo do arquivo), a Stream com o conteúdo do arquivo e o seu “mime type“.

Se você não sabe o que é “mime type“, ele é um identificador que serve para definir o tipo de um arquivo. Por exemplo, “text/plain” é o “mime type” para arquivos texto, “image/jpeg” é o “mime type” para imagens jpg, e por aí vai. Esse tipo de identificador é muito utilizado em aplicações web na hora de fazer uma requisição.

Para nos ajudar com o cálculo do “mime type” no nosso projeto de exemplo, vamos utilizar a biblioteca MimeTypeMap, que é basicamente um dicionário gigante de “mime types” por extensão de arquivo. Adicione uma referência a essa biblioteca procurando por “MediaTypeMap” no NuGet:

Em seguida, vamos implementar o método que fará o upload do arquivo:

        // C#
        private static void Upload(Google.Apis.Drive.v3.DriveService servico, string caminhoArquivo)
        {
            var arquivo = new Google.Apis.Drive.v3.Data.File();
            arquivo.Name = System.IO.Path.GetFileName(caminhoArquivo);
            arquivo.MimeType = MimeTypes.MimeTypeMap.GetMimeType(System.IO.Path.GetExtension(caminhoArquivo));
            using (var stream = new System.IO.FileStream(caminhoArquivo, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                var request = servico.Files.Create(arquivo, stream, arquivo.MimeType);
                request.Upload();
            }
        }
    ' VB.NET
    Private Sub Upload(Servico As Google.Apis.Drive.v3.DriveService, CaminhoArquivo As String)
        Dim Arquivo = New Google.Apis.Drive.v3.Data.File()
        Arquivo.Name = System.IO.Path.GetFileName(CaminhoArquivo)
        Arquivo.MimeType = MimeTypes.MimeTypeMap.GetMimeType(System.IO.Path.GetExtension(CaminhoArquivo))
        Using Stream = New System.IO.FileStream(CaminhoArquivo, System.IO.FileMode.Open, System.IO.FileAccess.Read)
            Dim Request = Servico.Files.Create(Arquivo, Stream, Arquivo.MimeType)
            Request.Upload()
        End Using
    End Sub

Pronto! Para fazermos o upload de um arquivo chamado “arquivo.txt” que se encontra na pasta “bin/debug” da nossa aplicação, o código que teríamos que colocar no bloco “using” seria este:

                // C#
                Console.Clear();
                Console.WriteLine("Upload");
                Upload(servico, "arquivo.txt");
                Console.WriteLine("Fim Upload");
                Console.ReadLine();
            ' VB.NET
            Console.Clear()
            Console.WriteLine("Upload")
            Upload(Servico, "arquivo.txt")
            Console.WriteLine("Fim Upload")
            Console.ReadLine()

E este seria o resultado no nosso Google Drive:

Tudo isso funciona muito bem da primeira vez que executarmos esse código. Porém, se executarmos uma segunda vez, ao invés do arquivo ser substituído, um novo “arquivo.txt” será criado no nosso Google Drive. É simplesmente incompreensível o fato do Google Drive trabalhar dessa maneira, possibilitando que existam dois arquivos com o mesmo nome no mesmo diretório. Mas, enfim, é assim que ele funciona.

Para corrigirmos esse problema (ou seja, substituirmos o arquivo caso ele já exista), teremos que detectar se o arquivo já existe e, caso positivo, temos que utilizar o método “Files.Update“, ao invés de “Files.Create“:

        // C#
        private static void Upload(Google.Apis.Drive.v3.DriveService servico, string caminhoArquivo)
        {
            var arquivo = new Google.Apis.Drive.v3.Data.File();
            arquivo.Name = System.IO.Path.GetFileName(caminhoArquivo);
            arquivo.MimeType = MimeTypes.MimeTypeMap.GetMimeType(System.IO.Path.GetExtension(caminhoArquivo));

            using (var stream = new System.IO.FileStream(caminhoArquivo, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                var ids = ProcurarArquivoId(servico, arquivo.Name);
                Google.Apis.Upload.ResumableUpload<Google.Apis.Drive.v3.Data.File, Google.Apis.Drive.v3.Data.File> request;

                if (ids == null || !ids.Any())
                {
                    request = servico.Files.Create(arquivo, stream, arquivo.MimeType);
                }
                else
                {
                    request = servico.Files.Update(arquivo, ids.First(), stream, arquivo.MimeType);
                }

                request.Upload();
            }
        }
    ' VB.NET
    Private Sub Upload(Servico As Google.Apis.Drive.v3.DriveService, CaminhoArquivo As String)
        Dim Arquivo = New Google.Apis.Drive.v3.Data.File()
        Arquivo.Name = System.IO.Path.GetFileName(CaminhoArquivo)
        Arquivo.MimeType = MimeTypes.MimeTypeMap.GetMimeType(System.IO.Path.GetExtension(CaminhoArquivo))

        Using Stream = New System.IO.FileStream(CaminhoArquivo, System.IO.FileMode.Open, System.IO.FileAccess.Read)
            Dim Ids = ProcurarArquivoId(Servico, Arquivo.Name)
            Dim Request As Google.Apis.Upload.ResumableUpload(Of Google.Apis.Drive.v3.Data.File, Google.Apis.Drive.v3.Data.File)

            If Ids Is Nothing OrElse Not Ids.Any() Then
                Request = Servico.Files.Create(Arquivo, Stream, Arquivo.MimeType)
            Else
                Request = Servico.Files.Update(Arquivo, Ids.First(), Stream, Arquivo.MimeType)
            End If

            Request.Upload()
        End Using
    End Sub

Agora sim. Se executarmos esse código mais de uma vez, ele simplesmente substituirá o “arquivo.txt” já existente no nosso Google Drive, utilizando o conteúdo da nova “Stream“.

Baixando um arquivo do Google Drive

Até agora nós já vimos como listar arquivos no Google Drive e como criar e deletar pastas e arquivos. O que é que está faltando? O download de arquivos! Esse é um dos procedimentos mais tranquilos de serem feitos com a API do Google Drive. Nós só temos que criar um request com o método “Files.Get” passando o “id” do arquivo a ser baixado e, em seguida, chamamos o método “Download” passando a “Stream” onde o arquivo deverá ser salvo. Veja só como é simples:

        // C#
        private static void Download(Google.Apis.Drive.v3.DriveService servico, string nome, string destino)
        {
            var ids = ProcurarArquivoId(servico, nome);
            if (ids != null && ids.Any())
            {
                var request = servico.Files.Get(ids.First());
                using (var stream = new System.IO.FileStream(destino, System.IO.FileMode.Create, System.IO.FileAccess.Write))
                {
                    request.Download(stream);
                }
            }
        }
    ' VB.NET
    Private Sub Download(Servico As Google.Apis.Drive.v3.DriveService, Nome As String, Destino As String)
        Dim Ids = ProcurarArquivoId(Servico, Nome)
        If Ids IsNot Nothing AndAlso Ids.Any() Then
            Dim Request = Servico.Files.[Get](Ids.First())
            Using Stream = New System.IO.FileStream(Destino, System.IO.FileMode.Create, System.IO.FileAccess.Write)
                Request.Download(Stream)
            End Using
        End If
    End Sub

Para baixarmos o “arquivo.txt” que fizemos o upload na seção anterior, a chamada ficaria assim:

                // C#
                Console.Clear();
                Console.WriteLine("Download");
                Download(servico, "arquivo.txt", "arquivoBaixado.txt");
                Console.WriteLine("Fim Download");
                Console.ReadLine();
            ' VB.NET
            Console.Clear()
            Console.WriteLine("Download")
            Download(Servico, "arquivo.txt", "arquivoBaixado.txt")
            Console.WriteLine("Fim Download")
            Console.ReadLine()

Enviando um item para a lixeira

Por fim, a última coisa que quero mostrar para você neste artigo é: como enviamos um item para a lixeira? Na segunda versão da API do Google Drive, nós tínhamos à nossa disposição um método específico para enviar um item para a lixeira. Porém, na terceira versão da API a Google decidiu remover esse método.

Para enviarmos um item para a lixeira, nós temos que recuperar o seu “id“, criar uma instância da classe “File” e marcar a propriedade “Trashed” como verdadeiro. Em seguida, nós criamos um request para o método “Files.Update” enviando essa instância de “File“:

        // C#
        private static void MoverParaLixeira(Google.Apis.Drive.v3.DriveService servico, string nome)
        {
            var ids = ProcurarArquivoId(servico, nome);
            if (ids != null && ids.Any())
            {
                foreach (var id in ids)
                {
                    var arquivo = new Google.Apis.Drive.v3.Data.File();
                    arquivo.Trashed = true;
                    var request = servico.Files.Update(arquivo, id);
                    request.Execute();
                }
            }
        }
    ' VB.NET
    Private Sub MoverParaLixeira(Servico As Google.Apis.Drive.v3.DriveService, Nome As String)
        Dim Ids = ProcurarArquivoId(Servico, Nome)
        If Ids IsNot Nothing AndAlso Ids.Any() Then
            For Each Id In Ids
                Dim Arquivo = New Google.Apis.Drive.v3.Data.File()
                Arquivo.Trashed = True
                Dim Request = Servico.Files.Update(Arquivo, Id)
                Request.Execute()
            Next
        End If
    End Sub

A chamada desse método não tem segredo. Basta passarmos o nome do arquivo ou pasta que deverá ser mandado para a lixeira:

                // C#
                Console.Clear();
                Console.WriteLine("Lixeira");
                MoverParaLixeira(servico, "arquivo.txt");
                Console.WriteLine("Fim Lixeira");
                Console.ReadLine();
            ' VB.NET
            Console.Clear()
            Console.WriteLine("Lixeira")
            MoverParaLixeira(Servico, "arquivo.txt")
            Console.WriteLine("Fim Lixeira")
            Console.ReadLine()

E no ASP.NET MVC?

Se você tentar rodar esse mesmo código no ASP.NET MVC, você ficará a princípio contente porque ele funciona perfeitamente enquanto estamos debugando o projeto com o Visual Studio. Porém, ao publicá-lo em qualquer servidor, na hora de autenticar o acesso, a página de confirmação não será exibida e você receberá um erro “Access Denied“. Como resolvemos isso?

Depois de horas testando a ajustando o projeto, eu finalmente consegui fazer a API do Google Drive autenticar no MVC. Eu segui os passos deste tutorial da própria Google, com algumas pequenas correções.

Primeiramente, nós temos que criar uma outra credencial que também possibilite o acesso ao Google Drive pela web (a credencial que nós criamos anteriormente só vale para aplicativos desktop). Para isso, vá até o seu painel de credenciais e escolha a opção “Create credentials -> OAuth Client ID“:

Em seguida, escolha a opção “Web Application”:

E aí vem uma parte muito importante: as URLs de redirecionamento. Nessa área você deve colocar a URL da página onde você vai acessar o seu Google Drive, precedida de “/AuthCallback“. Por exemplo, no meu projeto eu acesso o Google Drive através da view “GoogleDrive/Index“. Por isso, eu coloquei as seguintes URLs de redirecionamento na minha credencial:

Note que eu adicionei uma URL com o endereço final do meu site (publicado no Azure) e uma URL com o endereço apontando para o localhost + porta. Isso fará com que o projeto funcione tanto em modo de debug local quanto no servidor onde a aplicação será publicada. Além disso, eu adicionei tanto a URL com final “Index” como com final “IndexAsync“. Eu não tenho certeza se realmente precisamos tanto da URL com final “Async” e sem final “Async“, mas em alguns testes que eu fiz, o acesso só funcionou quando eu coloquei as duas URLs como redirecionamento.

O próximo passo é adicionarmos a referência à biblioteca “Google.Apis.Auth.Mvc” pelo NuGet. Essa biblioteca tem alguns helpers que nos ajudarão a fazer a autenticação do Google Drive através do MVC.

Uma vez adicionada essa biblioteca, nós temos que incluir uma nova classe chamada “AppFlowMetadata” no nosso projeto. O código dessa classe deverá ser o seguinte:

    // C#
    public class AppFlowMetadata : Google.Apis.Auth.OAuth2.Mvc.FlowMetadata
    {
        private static readonly Google.Apis.Auth.OAuth2.Flows.IAuthorizationCodeFlow flow =
            new Google.Apis.Auth.OAuth2.Flows.GoogleAuthorizationCodeFlow(new Google.Apis.Auth.OAuth2.Flows.GoogleAuthorizationCodeFlow.Initializer
            {
                ClientSecrets = new Google.Apis.Auth.OAuth2.ClientSecrets
                {
                    ClientId = "SEU_ID",
                    ClientSecret = "SEU_SECRET"
                },
                Scopes = new[] { Google.Apis.Drive.v3.DriveService.Scope.Drive },
                DataStore = new Google.Apis.Util.Store.FileDataStore("Drive.Api.Auth.Store")
            });

        public override string GetUserId(System.Web.Mvc.Controller controller)
        {
            // In this sample we use the session to store the user identifiers.
            // That's not the best practice, because you should have a logic to identify
            // a user. You might want to use "OpenID Connect".
            // You can read more about the protocol in the following link:
            // https://developers.google.com/accounts/docs/OAuth2Login.
            var user = controller.Session["user"];
            if (user == null)
            {
                user = Guid.NewGuid();
                controller.Session["user"] = user;
            }
            return user.ToString();

        }

        public override Google.Apis.Auth.OAuth2.Flows.IAuthorizationCodeFlow Flow
        {
            get { return flow; }
        }
    }
' VB.NET
Public Class AppFlowMetadata
    Inherits Google.Apis.Auth.OAuth2.Mvc.FlowMetadata
    Private Shared ReadOnly m_flow As Google.Apis.Auth.OAuth2.Flows.IAuthorizationCodeFlow = New Google.Apis.Auth.OAuth2.Flows.GoogleAuthorizationCodeFlow(New Google.Apis.Auth.OAuth2.Flows.GoogleAuthorizationCodeFlow.Initializer() With {
        .ClientSecrets = New Google.Apis.Auth.OAuth2.ClientSecrets() With {
            .ClientId = "SEU_ID",
            .ClientSecret = "SEU_SECRET"
        },
        .Scopes = New String() {Google.Apis.Drive.v3.DriveService.Scope.Drive},
        .DataStore = New Google.Apis.Util.Store.FileDataStore("Drive.Api.Auth.Store")
    })

    Public Overrides Function GetUserId(controller As System.Web.Mvc.Controller) As String
        ' In this sample we use the session to store the user identifiers.
        ' That's not the best practice, because you should have a logic to identify
        ' a user. You might want to use "OpenID Connect".
        ' You can read more about the protocol in the following link:
        ' https://developers.google.com/accounts/docs/OAuth2Login.
        Dim user = controller.Session("user")
        If user Is Nothing Then
            user = Guid.NewGuid()
            controller.Session("user") = user
        End If
        Return user.ToString()

    End Function

    Public Overrides ReadOnly Property Flow() As Google.Apis.Auth.OAuth2.Flows.IAuthorizationCodeFlow
        Get
            Return m_flow
        End Get
    End Property
End Class

Nota: não esqueça de substituir “SEU_ID” e “SEU_SECRET” utilizando as informações disponibilizadas no portal de credenciais do Google. Provavelmente é possível ajustarmos essa implementação de forma que o arquivo de credenciais seja carregado (ao invés de informarmos o ID e segredo direto no código), mas eu não consegui encontrar um tempo para fazer esse ajuste. Se você conseguir ajustar, mande o código nos comentários.

Em seguida, temos que adicionar um novo controller no nosso projeto. O nome desse controller deve ser “AuthCallbackController” e o seu código deve ser o seguinte:

    // C#
    public class AuthCallbackController : Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController
    {
        protected override Google.Apis.Auth.OAuth2.Mvc.FlowMetadata FlowData
        {
            get { return new AppFlowMetadata(); }
        }
    }
    ' VB.NET
    Public Class AuthCallbackController
        Inherits Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController
        Protected Overrides ReadOnly Property FlowData() As Google.Apis.Auth.OAuth2.Mvc.FlowMetadata
            Get
                Return New AppFlowMetadata()
            End Get
        End Property
    End Class

Por fim, agora nós podemos adicionar o controller que, de fato, fará o acesso ao nosso Google Drive e listará o seu conteúdo. Dentro desse controller, criamos um método (por exemplo, “Index“) com o seguinte código:

        // C#
        public async System.Threading.Tasks.Task<ActionResult> Index(System.Threading.CancellationToken cancellationToken)
        {
            var result = await new Google.Apis.Auth.OAuth2.Mvc.AuthorizationCodeMvcApp(this, new AppFlowMetadata()).
                AuthorizeAsync(cancellationToken);

            if (result.Credential != null)
            {
                var service = new Google.Apis.Drive.v3.DriveService(new Google.Apis.Services.BaseClientService.Initializer
                {
                    HttpClientInitializer = result.Credential,
                    ApplicationName = "ASP.NET MVC Sample"
                });

                ViewBag.Arquivos = ListarArquivos(service);

                return View();
            }
            else
            {
                return new RedirectResult(result.RedirectUri);
            }
        }
        ' VB.NET
        Public Async Function Index(cancellationToken As System.Threading.CancellationToken) As System.Threading.Tasks.Task(Of ActionResult)
            Dim result = Await New Google.Apis.Auth.OAuth2.Mvc.AuthorizationCodeMvcApp(Me, New AppFlowMetadata()).AuthorizeAsync(cancellationToken)

            If result.Credential IsNot Nothing Then
                Dim service = New Google.Apis.Drive.v3.DriveService(New Google.Apis.Services.BaseClientService.Initializer() With {
            .HttpClientInitializer = result.Credential,
            .ApplicationName = "ASP.NET MVC Sample"})

                ViewBag.Arquivos = ListarArquivos(service)

                Return View()
            Else
                Return New RedirectResult(result.RedirectUri)
            End If
        End Function

E a view ficaria assim:

<!--C#-->
@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>
@foreach (var item in ViewBag.Arquivos)
{
    <div>@item</div>
}
<!--VB.NET-->
@Code
    ViewData("Title") = "Index"
End Code
<h2>Index</h2>
@For Each Item In ViewBag.Arquivos
@<div>@item</div>
Next Item

Pronto! E com isso nós temos o nosso site MVC acessando o Google Drive com sucesso! Agora você pode ajustar esse código implementando os outros métodos que nós conferimos no início deste artigo.

Concluindo

O acesso à API do Google Drive em projetos .NET não é tão complicado de se implementar. Existem alguns detalhes que são chatos, mas, uma vez que entendemos o funcionamento da API, fica fácil de fazer qualquer tipo de manipulação do Google Drive a partir da nossa aplicação.

No artigo de hoje você aprendeu a habilitar a API do Google Drive na sua conta, bem como a geração do arquivo de credenciais que é necessário para o seu acesso. Em seguida, vimos como listar, fazer o upload, download e exclusão de arquivos do Google Drive no C# e VB.NET. Além disso, nós conferimos também como mandar itens para a lixeira. Por fim, nós vimos como ajustar o código de autorização de forma que ele funcione também em projetos ASP.NET MVC.

E você, já precisou fazer alguma integração com o Google Drive nas suas aplicações? Já pensou na possibilidade de armazenar alguns dados da sua aplicação na sua conta do Google Drive? Quem sabe algum backup ou disponibilizar novas versões da aplicação? Conte pra gente nos comentários a sua experiência com o Google Drive ou talvez as ideias que você teve após ter lido este artigo.

Baixe o projeto de exemplo

Para baixar o projeto de exemplo desse artigo, assine a minha newsletter. Ao fazer isso, além de ter acesso ao projeto, você receberá um e-mail toda semana sobre o artigo publicado e ficará sabendo também em primeira mão sobre o artigo da próxima semana, além de receber dicas “bônus” que eu só compartilho por e-mail. Inscreva-se utilizando o formulário no final do artigo.

Até a próxima!

André Lima

Newsletter do André Lima

* indicates required



Powered by MailChimp

45 thoughts on “Utilizando a API do Google Drive no C# e VB.NET

  • Ricardo disse:

    Olá, mesmo assinando a newslatter não encontro o link pra baixar os exemplos :)

  • Marlon Tiedt disse:

    Parabéns pelo post.
    Só uma grande dúvida, você conseguiu implementar o Google Drive Api em MVC?

    Tenho um projeto que somente funciona em ambiente local, e no servidor não funciona nem a pau. Para na linha

    Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.AuthorizeAsync

    Teria alguma dica?

    • andrealveslima disse:

      Olá Marlon, obrigado pelo comentário!

      Sendo sincero com você, eu não testei o código em um projeto MVC.. A única coisa que eu imagino que possa dar errado nesse processo é a hora em que a API abre o browser para você autorizar o acesso do aplicativo ao Google Drive.. Se estiver rodando no IIS, acredito que isso possa dar algum problema..

      Aliás, pesquisando aqui eu acabei de achar que aparentemente esse é realmente o problema.. Você já chegou a dar uma olhada nesta thread do StackOverflow:

      GoogleWebAuthorizationBroker in MVC For Google Drive Access

      ?

      Se eu conseguir um tempo nessa semana eu testo aqui em um projeto MVC para ver se eu consigo fazer funcionar.. Se você conseguir com as informações desse link do StackOverflow, me avisa..

      Abraço!
      André Lima

    • andrealveslima disse:

      Olá Marlon!

      Consegui fazer funcionar no MVC.. Eu adicionei uma seção aqui no artigo mostrando os ajustes que eu tive que fazer no projeto MVC.. Dá uma olhada e me avisa se funcionou no seu projeto..

      Abraço!
      André Lima

  • Wilson de Oliveira disse:

    Sensancional.

  • Petronio Filho disse:

    Olá André!

    Gostaria de fazer o download do código. Já estou na sua newslatter.

    email: camposfilho84@gmail.com

  • Dario Ferreira Franca disse:

    Tem como implementar uma progressbar na parte de dawnload poderia colocar um exemplo?

    • andrealveslima disse:

      Olá Dario, obrigado pelo comentário!

      Nunca implementei isso, mas dei uma pesquisada aqui e encontrei uma informação interessante no StackOverflow.. O Request tem uma propriedade chamada MediaDownloader que, por sua vez, tem um evento chamado ProgressChanged.. Com esse evento, você sempre tem a quantidade de bytes que já foram baixados até o momento.. Dividindo essa informação pela quantidade de bytes total do arquivo que está sendo baixado, você tem o progresso em porcentagem, que você poderia utilizar em uma progress bar no seu projeto..

      Você já tentou fazer dessa maneira?

      Abraço!
      André Lima

  • Ricardo disse:

    102/5000
    Olá, quando eu envio não me dá erro, mas não o arquivo é enviado, eu preciso de sua ajuda, obrigado

    • andrealveslima disse:

      Olá Ricardo, obrigado pelo comentário!

      Como é que está exatamente o seu código? Idêntico ao que eu postei aqui no site ou você fez alguma alteração? Você poderia enviar o seu código e um screenshot (por e-mail, se preferir) para eu conseguir entender melhor o erro que está acontecendo aí no seu projeto?

      Abraço!
      André Lima

  • James Maxwel disse:

    Grande artigo amigo, muito bem elaborado e obrigado por compartilhar seu conhecimento.

    Gostaria de sugerir uma correção quanto aos tipos de credenciais que mencionaste.

    A primeira “User Data” é necessário quando sua aplicação necessita gerenciar os arquivos do usuário, isto exige o consentimento do mesmo;

    Já a segunda “Application Data” é necessário quando sua aplicação gerencia sua própria conta no drive e para isto não necessita do consentimento do usuário tendo em vista que você já possui estes dados.

    Abraço
    James Maxwel

    • andrealveslima disse:

      Olá James, muito obrigado pelo comentário!

      Agradeço também por você ter feito essa correção quanto aos tipos de credenciais.. Já adicionei a correção no texto do artigo.. Valeu! :)

      Abraço!

  • James Maxwel disse:

    André Lima, seria possível retomar o download de onde ele parou? não estou conseguindo alterara requisição(não sei como atribuir o range no header do request)
    estou desenvolvendo em VB.Net

    • andrealveslima disse:

      Olá novamente James!

      Infelizmente eu não faço ideia de como podemos pausar e resumir o download de arquivos com a API do Google Drive.. Coloquei esse ponto aqui na minha lista e, assim que eu conseguir pesquisar, eu te aviso.. Se você conseguir resolver antes, volta aqui e conta pra gente como você resolveu.. Aí eu adiciono essa parte no artigo também..

      Abraço!
      André Lima

  • Jesus disse:

    Saludos, example code?…

  • Arilo Camilo de Souza disse:

    Boa tarde,André, td bem?

    Gostei muito do seu artigo sobre integração com o Google Drive…
    Aqui onde trabalho,estou tentando fazer algo parecido..
    O problema é: Não há na documentação do Google, as DLL e o código para implementar o download, upload , autenticação e listagem de arquivos quando a aplicação é do tipo Webforms. Não dá pra importar essas DLL pq são específicas do MVC.
    Tem alguma dica?

    • andrealveslima disse:

      Olá Arilo, muito obrigado pelo comentário!

      Nunca implementei as funcionalidades do Google Drive em um projeto Web Forms, mas acredito que não deva ser muito diferente do MVC.. Primeiramente, as classes “base” da API do Google Drive funcionam em todas as plataformas, inclusive Console, Windows Forms, WPF, etc.. Essas classes você pode utilizar no Web Forms com certeza (ou seja, o código do upload, download, etc será idêntico ao que eu apresentei aqui neste artigo).. A grande diferença será na autenticação..

      No final do artigo eu mostrei como fazer a autenticação com o MVC, utilizando aquela classe helper do NuGet (Google.Apis.Auth.Mvc).. No próprio NuGet tem outra classe helper para projetos web, sem ser MVC (Google.Apis.Oauth2.v2).. Você já chegou a dar uma olhada nela?

      E tem este artigo aqui que mostra como fazer a implementação no Web Forms (eu não testei):

      Google Drive API v2 for ASP.Net webforms

      Dá uma olhada e depois avisa se ajudou em algo..

      Abraço!
      André Lima

  • joao batista disse:

    Apesar de ter feito todo cadastro não acho como acessar a sua newsletter.
    Por favor pode informar ou mandar um link de acesso

    • andrealveslima disse:

      Olá João!

      Acredito que você estava querendo acessar os projetos de exemplo, correto? Se for isso, eu mandei o link no seu e-mail.. Se for outra coisa, é só avisar..

      Abraço!
      André Lima

  • Thiago Monteiro disse:

    Boa tarde,André, td bem?

    Muito bom esse artigo, estou com uma dúvida que não consegui encontrar na internet, pode me ajudar?
    Seria em como enviar um arquivo para uma determinada pasta, procurei em vários lugares e não encontrei. Obrigado

    • andrealveslima disse:

      Olá Thiago, muito obrigado pelo comentário!

      Para adicionar um arquivo em uma pasta específica, você precisa primeiro pegar o ID da pasta e depois setar na propriedade “Parents” do arquivo:

                  arquivo.MimeType = MimeTypes.MimeTypeMap.GetMimeType(System.IO.Path.GetExtension(caminhoArquivo));           
                  var idPasta = ProcurarArquivoId(servico, "NovoDiretorio").First();
                  arquivo.Parents = new List<string>(new string[] { idPasta });
      

      Depois, na hora de criar o request, você precisa adicionar na lista de fields a coluna “parents”:

                      if (ids == null || !ids.Any())
                      {
                          var theRequest = servico.Files.Create(arquivo, stream, arquivo.MimeType);
                          theRequest.Fields = "id, parents";
                          request = theRequest;
                      }
      

      Testa aí e depois me fala se funcionou..

      Abraço!
      André Lima

  • Olá André, boa noite.
    Estou com problemas no meu atualizador de arquivos, pois ele fica a todo momento solicitando credenciais de acesso.
    Eu gostaria de saber se você teria ai um exemplo usando a autenticação do tipo “Credenciais padrão do aplicativo”, no seu exemplo você usa UserCredential
    Muito obrigado

    • andrealveslima disse:

      Olá Renan!

      Que estranho hein.. Qual é o tipo de projeto? Console, desktop, web? No exemplo que eu mostrei no artigo, ele só pede as credenciais uma vez, aí fica armazenado o token em disco para as próximas execuções da aplicação.. Você chegou a testar exatamente esse código que eu mostrei no artigo?

      Abraço!
      André Lima

  • Braga disse:

    Prezado Andre, boa tarde!

    Gostei muito do seu artigo:
    http://www.andrealveslima.com.br/blog/index.php/2017/04/12/utilizando-api-google-drive-no-c-e-vb-net/

    Assinei a newletter, confirmei o email, porém quando aparece para baixar o código, me vem um link diverso, veja:


    Inscrição confirmada
    Sua assinatura de nossa lista foi confirmada.

    Clique nos links abaixo para fazer o download dos seus brindes:

    Lista de Recursos do Report Viewer
    Resumo em tópicos: 80/20 Sales and Marketing

    Agradecemos a inscrição!

    Esses dois links não tem relação com o artigo, estou informando para te pedir o código, mas também para que você fiquei ciente, para poder arrumar o problema.

    Poderia me enviar o código no email?

    Att

    • andrealveslima disse:

      Olá Braga!

      Respondi o seu e-mail com a mesma dúvida.. Se quiser, podemos continuar a discussão por lá ou por aqui mesmo..

      Abraço!
      André Lima

  • Everson Jean disse:

    Olá, queria saber como upar um arquivo em determinada pasta do GDrive, já andei procurando o código pra isto mas não encontrei :(

  • Marcos H. Horst Cavalli disse:

    Cara, estou recebendo o erro “At least one client secrets (Installed or Web) should be set” ao tentar autenticar(ocorre no seguinte trecho:
    cred = Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.AuthorizeAsync(
    Google.Apis.Auth.OAuth2.GoogleClientSecrets.Load(stream).Secrets,
    new[] { Google.Apis.Drive.v3.DriveService.Scope.Drive },
    “user”, System.Threading.CancellationToken.None,
    new Google.Apis.Util.Store.FileDataStore(diretorioCredenciais, true)).Result;)
    Está a copia do seu, porém não faço a menor ideia de como consertar, poderia me ajudar com isto?

    • Marcos H. Horst Cavalli disse:

      Acabei conseguindo corrigir esta versão, porém agora ele está abrindo uma guia no google chrome totalmente cinza com a carinha infeliz como icone da página….sabe o que poderia ser?

      • andrealveslima disse:

        Olá Marcos!

        Não tenho a mínima ideia.. Você está tentando executar isso na sua casa ou na empresa / faculdade? Será que você não está atrás de um proxy ao acessar a internet? Você tentou baixar o projeto de exemplo para testar com ele?

        Abraço!
        André Lima

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *