Documente Academic
Documente Profesional
Documente Cultură
VB.NET
andrealveslima | .NET, Software Development | 154
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.
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.
return credenciais;
}
1 ' VB.NET
2 Private Function Autenticar() As
3 Google.Apis.Auth.OAuth2.UserCredential
4 Dim Credenciais As Google.Apis.Auth.OAuth2.UserCredential
5
6 Using Stream = New System.IO.FileStream("client_id.json",
7 System.IO.FileMode.Open, System.IO.FileAccess.Read)
8 Dim DiretorioAtual =
9 System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExe
10 cutingAssembly().Location)
11 Dim DiretorioCredenciais =
System.IO.Path.Combine(DiretorioAtual, "credential")
Credenciais =
Google.Apis.Auth.OAuth2.GoogleWebAuthorizationBroker.AuthorizeAsy
nc(
Google.Apis.Auth.OAuth2.GoogleClientSecrets.Load(Stre
12
am).Secrets,
13
New String()
14 {Google.Apis.Drive.v3.DriveService.Scope.DriveReadonly},
15 "user",
16 System.Threading.CancellationToken.None,
17 New
18 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#
1 private static Google.Apis.Drive.v3.DriveService
2 AbrirServico(Google.Apis.Auth.OAuth2.UserCredential credenciais)
3{
4 return new Google.Apis.Drive.v3.DriveService(new
5 Google.Apis.Services.BaseClientService.Initializer()
6 {
7 HttpClientInitializer = credenciais
8 });
}
1 ' VB.NET
2 Private Function AbrirServico(Credenciais As
3 Google.Apis.Auth.OAuth2.UserCredential) As
Google.Apis.Drive.v3.DriveService
Return New Google.Apis.Drive.v3.DriveService(New
4 Google.Apis.Services.BaseClientService.Initializer() With {
5 .HttpClientInitializer = Credenciais
6 })
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:
1 // C#
2 var credenciais = Autenticar();
3
4 using (var servico = AbrirServico(credenciais))
5{
6}
1 ' VB.NET
2 Dim Credenciais = Autenticar()
3
4 Using Servico = AbrirServico(Credenciais)
5
6 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:
1 // C#
2 private static void
3 ListarArquivos(Google.Apis.Drive.v3.DriveService servico)
4 {
5 var request = servico.Files.List();
6 request.Fields = "files(id, name)";
7 var resultado = request.Execute();
var arquivos = resultado.Files;
8
9
if (arquivos != null && arquivos.Any())
10
{
11 foreach (var arquivo in arquivos)
12 {
13 Console.WriteLine(arquivo.Name);
14 }
15 }
16 }
' VB.NET
1
Private Sub ListarArquivos(Servico As
2
Google.Apis.Drive.v3.DriveService)
3
Dim Request = Servico.Files.List()
4
Request.Fields = "files(id, name)"
5 Dim Resultado = Request.Execute()
6 Dim Arquivos = Resultado.Files
7
8 If Arquivos IsNot Nothing AndAlso Arquivos.Any() Then
9 For Each Arquivo In Arquivos
10 Console.WriteLine(Arquivo.Name)
11 Next
12 End If
13 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:
1 // C#
2 Console.WriteLine("Listagem");
3 ListarArquivos(servico);
4 Console.WriteLine("Fim Listagem");
5 Console.ReadLine();
1 ' VB.NET
2 Console.WriteLine("Listagem")
3 ListarArquivos(Servico)
4 Console.WriteLine("Fim Listagem")
5 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:
1 // C#
2 request.PageSize = 1000;
3 var resultado = request.Execute();
1 ' VB.NET
2 Request.PageSize = 1000
3 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:
1 // C#
2 request.Q = "trashed=false";
1 ' VB.NET
2 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:
1 // C#
2 private static void
3 ListarArquivosPaginados(Google.Apis.Drive.v3.DriveService
4 servico, int arquivosPorPagina)
5 {
6 var request = servico.Files.List();
7 request.Fields = "nextPageToken, files(id, name)";
8 //request.Q = "trashed=false";
// Default 100, máximo 1000.
9 request.PageSize = arquivosPorPagina;
var resultado = request.Execute();
10
var arquivos = resultado.Files;
11
12
while (arquivos != null && arquivos.Any())
13
{
14
foreach (var arquivo in arquivos)
15
{
16
Console.WriteLine(arquivo.Name);
17
}
18
19
if (resultado.NextPageToken != null)
20 {
21 Console.WriteLine("Digite ENTER para ir para a
22 próxima página");
23 Console.ReadLine();
24 request.PageToken = resultado.NextPageToken;
25 resultado = request.Execute();
26 arquivos = resultado.Files;
27 }
28 else
29 {
30 arquivos = null;
31 }
32 }
}
1 ' VB.NET
2 Private Sub ListarArquivosPaginados(Servico As
3 Google.Apis.Drive.v3.DriveService, ArquivosPorPagina As Integer)
4 Dim Request = Servico.Files.List()
5 Request.Fields = "nextPageToken, files(id, name)"
6 'Request.Q = "trashed=false"
7 ' Default 100, máximo 1000.
8 Request.PageSize = ArquivosPorPagina
9 Dim Resultado = Request.Execute()
10 Dim Arquivos = Resultado.Files
11
12 While Arquivos IsNot Nothing AndAlso Arquivos.Any()
13 For Each arquivo In Arquivos
14 Console.WriteLine(arquivo.Name)
15 Next
16
17 If Resultado.NextPageToken IsNot Nothing Then
18 Console.WriteLine("Digite ENTER para ir para a
19 próxima página")
20 Console.ReadLine()
21 Request.PageToken = Resultado.NextPageToken
22 Resultado = Request.Execute()
23 Arquivos = Resultado.Files
24 Else
25 Arquivos = Nothing
26 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:
1 // C#
2 Console.Clear();
3 Console.WriteLine("Listagem paginada");
4 ListarArquivosPaginados(servico, 10);
5 Console.WriteLine("Fim Listagem paginada");
6 Console.ReadLine();
1 ' VB.NET
2 Console.Clear()
3 Console.WriteLine("Listagem paginada")
4 ListarArquivosPaginados(Servico, 10)
5 Console.WriteLine("Fim Listagem paginada")
6 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#
1 private static void
2 CriarDiretorio(Google.Apis.Drive.v3.DriveService servico, string
3 nomeDiretorio)
4{
5 var diretorio = new Google.Apis.Drive.v3.Data.File();
6 diretorio.Name = nomeDiretorio;
7 diretorio.MimeType = "application/vnd.google-apps.folder";
8 var request = servico.Files.Create(diretorio);
9 request.Execute();
}
' VB.NET
1
Private Sub CriarDiretorio(Servico As
2
Google.Apis.Drive.v3.DriveService, NomeDiretorio As String)
3 Dim Diretorio = New Google.Apis.Drive.v3.Data.File()
4 Diretorio.Name = NomeDiretorio
5 Diretorio.MimeType = "application/vnd.google-apps.folder"
6 Dim Request = Servico.Files.Create(Diretorio)
7 Request.Execute()
8 End Sub
Para criarmos um diretório chamado “NovoDiretorio” temos que fazer a seguinte chamada dentro
do nosso bloco “using“:
1 // C#
2 Console.Clear();
3 Console.WriteLine("Criar diretório");
4 CriarDiretorio(servico, "NovoDiretorio");
5 Console.WriteLine("Fim Criar diretório");
6 Console.ReadLine();
1 ' VB.NET
2 Console.Clear()
3 Console.WriteLine("Criar diretório")
4 CriarDiretorio(Servico, "NovoDiretorio")
5 Console.WriteLine("Fim Criar diretório")
6 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:
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)
1{
var arquivo = new Google.Apis.Drive.v3.Data.File();
2
arquivo.Name = System.IO.Path.GetFileName(caminhoArquivo);
3
arquivo.MimeType =
4
MimeTypes.MimeTypeMap.GetMimeType(System.IO.Path.GetExtension(cam
5
inhoArquivo));
6
7
using (var stream = new System.IO.FileStream(caminhoArquivo,
8
System.IO.FileMode.Open, System.IO.FileAccess.Read))
9
{
10
var ids = ProcurarArquivoId(servico, arquivo.Name);
11 Google.Apis.Upload.ResumableUpload<Google.Apis.Drive.v3.D
12 ata.File, Google.Apis.Drive.v3.Data.File> request;
13
14 if (ids == null || !ids.Any())
15 {
16 request = servico.Files.Create(arquivo, stream,
17 arquivo.MimeType);
18 }
19 else
20 {
21 request = servico.Files.Update(arquivo, ids.First(),
22 stream, arquivo.MimeType);
23 }
24
request.Upload();
}
}
1 ' VB.NET
2 Private Sub Upload(Servico As Google.Apis.Drive.v3.DriveService,
3 CaminhoArquivo As String)
4 Dim Arquivo = New Google.Apis.Drive.v3.Data.File()
5 Arquivo.Name = System.IO.Path.GetFileName(CaminhoArquivo)
6 Arquivo.MimeType =
7 MimeTypes.MimeTypeMap.GetMimeType(System.IO.Path.GetExtension(Cam
8 inhoArquivo))
9
10 Using Stream = New System.IO.FileStream(CaminhoArquivo,
11 System.IO.FileMode.Open, System.IO.FileAccess.Read)
12 Dim Ids = ProcurarArquivoId(Servico, Arquivo.Name)
13 Dim Request As Google.Apis.Upload.ResumableUpload(Of
14 Google.Apis.Drive.v3.Data.File, Google.Apis.Drive.v3.Data.File)
15
16 If Ids Is Nothing OrElse Not Ids.Any() Then
17 Request = Servico.Files.Create(Arquivo, Stream,
18 Arquivo.MimeType)
19 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“.
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“:
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:
1 // C#
2 public class AppFlowMetadata :
3 Google.Apis.Auth.OAuth2.Mvc.FlowMetadata
4 {
5 private static readonly
6 Google.Apis.Auth.OAuth2.Flows.IAuthorizationCodeFlow flow =
7 new
8 Google.Apis.Auth.OAuth2.Flows.GoogleAuthorizationCodeFlow(new
9 Google.Apis.Auth.OAuth2.Flows.GoogleAuthorizationCodeFlow.Initial
10 izer
11 {
12 ClientSecrets = new
13 Google.Apis.Auth.OAuth2.ClientSecrets
14 {
15 ClientId = "SEU_ID",
16 ClientSecret = "SEU_SECRET"
17 },
18 Scopes = new[]
{ Google.Apis.Drive.v3.DriveService.Scope.Drive },
DataStore = new
Google.Apis.Util.Store.FileDataStore("Drive.Api.Auth.Store")
});
public override
Google.Apis.Auth.OAuth2.Flows.IAuthorizationCodeFlow Flow
{
get { return flow; }
}
}
1 ' VB.NET
2 Public Class AppFlowMetadata
3 Inherits Google.Apis.Auth.OAuth2.Mvc.FlowMetadata
4 Private Shared ReadOnly m_flow As
5 Google.Apis.Auth.OAuth2.Flows.IAuthorizationCodeFlow = New
6 Google.Apis.Auth.OAuth2.Flows.GoogleAuthorizationCodeFlow(New
7 Google.Apis.Auth.OAuth2.Flows.GoogleAuthorizationCodeFlow.Initial
8 izer() With {
9 .ClientSecrets = New
10 Google.Apis.Auth.OAuth2.ClientSecrets() With {
11 .ClientId = "SEU_ID",
12 .ClientSecret = "SEU_SECRET"
13 },
14 .Scopes = New String()
15 {Google.Apis.Drive.v3.DriveService.Scope.Drive},
16 .DataStore = New
17 Google.Apis.Util.Store.FileDataStore("Drive.Api.Auth.Store")
18 })
19
20 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
21
link:
22
'
23
https://developers.google.com/accounts/docs/OAuth2Login.
24
Dim user = controller.Session("user")
25 If user Is Nothing Then
26 user = Guid.NewGuid()
27 controller.Session("user") = user
28 End If
29 Return user.ToString()
30
31 End Function
32
33 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#
1 public class AuthCallbackController :
2 Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController
3{
4 protected override Google.Apis.Auth.OAuth2.Mvc.FlowMetadata
5 FlowData
6 {
7 get { return new AppFlowMetadata(); }
8 }
}
1 ' VB.NET
2 Public Class AuthCallbackController
3 Inherits
4 Google.Apis.Auth.OAuth2.Mvc.Controllers.AuthCallbackController
5 Protected Overrides ReadOnly Property FlowData() As
6 Google.Apis.Auth.OAuth2.Mvc.FlowMetadata
7 Get
8 Return New AppFlowMetadata()
End Get
9 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>
1 Index(System.Threading.CancellationToken cancellationToken)
2 {
3 var result = await new
4 Google.Apis.Auth.OAuth2.Mvc.AuthorizationCodeMvcApp(this, new
5 AppFlowMetadata()).
6 AuthorizeAsync(cancellationToken);
7
8 if (result.Credential != null)
9 {
10 var service = new Google.Apis.Drive.v3.DriveService(new
11 Google.Apis.Services.BaseClientService.Initializer
12 {
13 HttpClientInitializer = result.Credential,
14 ApplicationName = "ASP.NET MVC Sample"
15 });
16
17 ViewBag.Arquivos = ListarArquivos(service);
18
19 return View();
20 }
21 else
22 {
23 return new RedirectResult(result.RedirectUri);
}
}
1 ' VB.NET
2 Public Async Function Index(cancellationToken As
3 System.Threading.CancellationToken) As
4 System.Threading.Tasks.Task(Of ActionResult)
5 Dim result = Await New
6 Google.Apis.Auth.OAuth2.Mvc.AuthorizationCodeMvcApp(Me, New
7 AppFlowMetadata()).AuthorizeAsync(cancellationToken)
8
9 If result.Credential IsNot Nothing Then
10 Dim service = New Google.Apis.Drive.v3.DriveService(New
11 Google.Apis.Services.BaseClientService.Initializer() With {
12 .HttpClientInitializer = result.Credential,
13 .ApplicationName = "ASP.NET MVC Sample"})
14
15 ViewBag.Arquivos = ListarArquivos(service)
16
Return View()
Else
Return New RedirectResult(result.RedirectUri)
End If
End Function
E a view ficaria assim:
1 <!--C#-->
2 @{
3 ViewBag.Title = "Index";
4}
5 <h2>Index</h2>
6 @foreach (var item in ViewBag.Arquivos)
7{
8 <div>@item</div>
9 }
1 <!--VB.NET-->
2 @Code
3 ViewData("Title") = "Index"
4 End Code
5 <h2>Index</h2>
6 @For Each Item In ViewBag.Arquivos
7 @<div>@item</div>
8 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.