Janeiro de 2016

Volume 31 – Número 1

Windows 10 - Como usar a API REST do OneDrive em um aplicativo do Windows 10

Por Laurent Bugnion

Em estruturas anteriores, como o Windows Phone 8, a equipe do OneDrive fornecia um SDK que era bastante prático de usar, mas não dava muita liberdade ao desenvolvedor. Por exemplo, o mecanismo de logon só era possível por meio de um controle de botão interno, e o desenvolvedor não podia alterar sua aparência nem seu comportamento. Porém, o mais difícil era que essa experiência predefinida não permitia que o código fosse compartilhado entre plataformas.

Agora, no entanto, a equipe do OneDrive fornece uma API REST moderna baseada em solicitações HTTP (GET, POST, PUT, etc.). Essa é uma maneira flexível de interagir com o gigantesco armazenamento de arquivos em nuvem e compilar código para diferentes plataformas usando técnicas de compartilhamento de código bem conhecidas que podem ser executadas em todas as plataformas Windows e até mesmo no iOS e no Android com plataformas Xamarin.

Esta é a primeira metade de um artigo em duas partes e mostrará como aproveitar a nova API do OneDrive para criar aplicativos da UWP (Plataforma Universal do Windows). Primeiro, você saberá como a API REST funciona e como se espera que os desenvolvedores interajam com ela. Você verá como o usuário pode fazer logon no sistema usando o OAuth e como as operações do sistema de arquivos (navegação em pastas, obtenção de informações de arquivos, obtenção do conteúdo de arquivos, upload de arquivos e assim por diante) podem ser aproveitadas. Você também aprenderá a executar operações adicionais, como acessar a pasta Aplicativo e compartilhar um link para um item com amigos.

No próximo artigo, falarei sobre a nova PCL (Biblioteca de Classes Portátil) da equipe do OneDrive, que está encapsulando as operações aqui descritas em uma biblioteca prática que pode ser adicionada aos seus aplicativos da UWP, mas também a outras estruturas com suporte, como ASP.NET, Xamarin.iOS, Xamarin.Android ou Xamarin.Forms.

Observação: Além da PCL que pode ser usada nas plataformas Xamarin.Android e Xamarin.iOS, a equipe do OneDrive também fornece SDKs nativos para as duas plataformas.

O código de exemplo

Você pode baixar o código de exemplo em galasoft.ch/s/msdnonedrive. Ele mostra como um aplicativo da UWP simples pode usar a API REST de baixo nível para realizar operações no serviço OneDrive. Para demonstrar que o código pode ser facilmente portado, o mesmo aplicativo também é implementado para Xamarin.Android, e os mesmos princípios podem ser aplicados a outras plataformas.

Como entender a API REST

As APIs REST estão usando HTTP como protocolo de transporte e utilizam os métodos do protocolo (GET, POST, PUT, DELETE e outros) e códigos de erro padrão (200 Êxito, 400 Solicitação incorreta, 500 Erro do servidor e assim por diante). Cada ponto de entrada da API é acessível por meio de um URI exclusivo que também pode ter parâmetros. Em alguns casos, um método GET simples e uma cadeia de caracteres de consulta podem ser usados para enviar informações ao serviço e obter um resultado. Porém, também é possível compilar solicitações mais complexas utilizando POST para alguns objetos serializados para JSON.

As APIs REST estão se tornando cada vez mais difundidas, e os desenvolvedores deveriam ficar satisfeitos com isso, pois elas oferecem uma maneira bem compreendida de se comunicar com serviços Web. O mais importante: elas possibilitam a compilação de componentes portáteis em C# e a sua utilização em todas as plataformas com suporte. Outra grande vantagem é que o HTTP é baseado em texto, e as solicitações podem passar facilmente por firewalls e proxies.

No entanto, a comunicação com métodos HTTP de baixo nível pode parecer muito trabalhosa, principalmente para desenvolvedores que não estão acostumados com os últimos desenvolvimentos em programação assíncrona. A compilação de um cliente assíncrono usando retornos de chamada não era uma das experiências mais agradáveis para um desenvolvedor, devido ao aninhamento profundo e aos possíveis problemas de threading que poderiam surgir. Felizmente, duas melhorias relativamente recentes facilitaram muito o processo para programadores em C#: o componente HttpClient e as palavras-chave async/await. Por exemplo, para acessar a pasta Música do OneDrive, basta compilar um URI e enviar uma solicitação GET:

var uri = new Uri(
  "https://api.onedrive.com/v1.0/drive/special/music");
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
  new AuthenticationHeaderValue("Bearer", AccessToken);
var json = await client.GetStringAsync(uri);

O código JSON resultante pode ser desserializado (com a biblioteca JSON.NET, por exemplo), para que você obtenha um objeto .NET que é usado no aplicativo. Esse código (reconhecidamente sem tratamento de erros ou logon) mostra como uma operação complexa torna-se simples e fluida. Além disso, o código será executado sem problemas em qualquer plataforma à qual o HttpClient dê suporte, o que inclui o WPF (Windows Presentation Foundation), o ASP.NET, o Windows 10, o Xamarin e outros.

Como registrar o aplicativo

Para poder fazer uma chamada à API do OneDrive, você deve registrar o aplicativo no centro de desenvolvimento do OneDrive, configurá-lo e obter a chave de ID do Cliente. O mecanismo de registro é descrito em bit.ly/1GPBaWL.

Ao registrar o novo aplicativo, vá para a página Configurações de API e defina a configuração "Aplicativo cliente móvel ou de desktop" como "Sim". Todas as outras configurações podem ser mantidas no padrão. Em seguida, recupere a ID do Cliente na página Configurações de Aplicativo e salve-a para mais tarde.

É importante compreender os diferentes termos e para que cada ID é necessária:

  • ID do Cliente: Essa é uma ID exclusiva para o aplicativo da UWP. Pode haver vários aplicativos cliente que se conectem a serviços Microsoft com a mesma ID do Cliente, mas em geral é recomendável usar uma ID do Cliente por aplicativo. A ID do Cliente está vinculada a informações do aplicativo da UWP, como nome, ícone e assim por diante. A ID do Cliente é gerada quando o aplicativo é criado e nunca muda.
  • Segredo do Cliente: Trata-se de um identificador exclusivo que é gerado quando o aplicativo da UWP é criado. No entanto, esse código pode mudar durante o tempo de vida do aplicativo. Por exemplo, se achar que o Segredo do Cliente foi atacado por um hacker, você poderá gerar um novo segredo e atualizar seus aplicativos, e os aplicativos do hacker terão o acesso negado. Observe que o Segredo do Cliente geralmente é usado apenas em aplicativos de servidor.
  • ID de Usuário e Senha: Quando o usuário faz logon, ele é solicitado a digitar o nome de usuário e a senha. Graças ao OAuth, a interação de logon ocorre apenas entre o usuário e o OneDrive, sem o conhecimento do aplicativo cliente. Na prática, isso é feito usando um Modo de Exibição da Web em que a caixa de diálogo de logon é mostrada.
  • Token de Acesso: Quando um usuário faz logon com êxito, o serviço de autenticação retorna um Token de Acesso. Esse token é válido apenas por determinado período de tempo (60 minutos). Depois disso, o usuário deve fazer logon novamente. O token deve ser enviado com cada solicitação, para provar que o usuário foi autenticado. Esse modo de autenticação é chamado de Fluxo de Token na documentação.
  • Token de Atualização: Esse token pode ser solicitado pelo aplicativo e salvo para atualizar o Token de Acesso, caso ele tenha expirado. Isso poderá ser útil se o aplicativo for usado no modo em segundo plano por muito tempo e precisar atualizar dados periodicamente sem a interação do usuário. Esse modo de autenticação é chamado de Fluxo de Código e é descrito em bit.ly/1MQ3KOb. Neste artigo, só usarei o Fluxo de Token, que é mais fácil de implementar.

Como experimentar com um Token de Avaliação

Se você quer experimentar rapidamente algumas solicitações REST sem implementar a autenticação previamente, o Centro de Desenvolvimento do OneDrive permite obter um token de avaliação, válido por uma hora, que você pode usar executando estas etapas:

  • Vá para bit.ly/1MQ3KOb.
  • Localize a seção "Experimente agora" e clique no botão Obter Token.
  • Se necessário, entre e confirme que você autoriza o Centro de Desenvolvimento a acessar sua conta do OneDrive.
  • Depois que o logon tiver êxito, um token de avaliação será mostrado na janela da Web principal.
  • Crie um novo aplicativo da UWP chamado TrialOneDrive.
  • Abra MainPage.xaml e adicione um botão chamado TrialButton.
  • Abra MainPage.xaml.cs e adicione um manipulador de eventos para o evento de Clique do TrialButton, como mostrado no código da Figura 1. Observe que o manipulador de eventos deve usar a palavra-chave "async", pois todas as operações do OneDrive são assíncronas.
  • No código da Figura 1, substitua a cadeia de caracteres YOUR TRIAL TOKEN pelo token de avaliação que você copiou a partir do site do Centro de Desenvolvimento. Não copie as palavras "Authorization: bearer"!
  • Coloque um ponto de interrupção na última linha do manipulador de eventos para inspecionar a variável JSON.
  • Execute o aplicativo e clique no botão.
  • Inspecione o código JSON recuperado em uma janela Inspeção. Você deverá ver informações sobre a pasta Música, como nome, data de criação, data da última modificação, contagem de filhos, ID da pasta (que pode ser usada em várias operações do sistema de arquivos mais tarde), nome do usuário conectado e assim por diante.

Figura 1 Adição de um manipulador de eventos para o evento Clique do TrialButton

TrialButton.Click += async (s, e) =>
{
  var uri = new Uri(
    "https://api.onedrive.com/v1.0/drive/special/music");
  var client = new HttpClient();
  client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "YOUR TRIAL TOKEN");
  var json = await client.GetStringAsync(uri);
};

Lembre-se de que o token de avaliação expira após uma hora. Portanto, não se esqueça de obter um novo, se você quiser demonstrar o aplicativo para seu chefe!

Autenticação com o OAuth

Agora que você tem um aplicativo registrado e compreende os termos importantes, você pode implementar a autenticação. Eis aqui as etapas para fazer isso, que são ilustradas na Figura 2:

  1. O usuário inicia a autenticação, por exemplo, clicando em um botão.
  2. O aplicativo verifica se um Token de Acesso está disponível.
  3. Em caso afirmativo, o aplicativo já foi autenticado e o usuário pode passar para a próxima operação. Se nenhum Token de Acesso estiver disponível, o aplicativo navegará para uma página XAML que contém um Modo de Exibição da Web.
  4. A página XAML define a URL inicial do Modo de Exibição da Web para carregar a página do ponto de extremidade de autenticação. A página XAML também assina o evento WebNavigationCompleted do Modo de Exibição da Web para monitorar o tráfego nesse controle. Um pouco mais adiante neste artigo, você aprenderá como a URL inicial é estruturada.
  5. O Modo de Exibição da Web carrega o HTML do ponto de extremidade de autenticação.
  6. O usuário digita seu nome de usuário e sua senha na página de autenticação HTML. Observe que essa interação é estritamente entre o usuário e o servidor do OneDrive. A página XAML funciona apenas como um contêiner.
  7. O usuário pressiona o botão HTML que envia o formulário ao servidor de autenticação. Se o usuário tiver configurado isso, páginas adicionais serão mostradas para lidar com a autenticação de dois fatores.
  8. Se as credenciais estiverem corretas, o servidor de autenticação redirecionará o Modo de Exibição da Web para uma URL especial que indicará um logon bem-sucedido. Essa URL também terá o Token de Acesso como um de seus parâmetros de cadeia de caracteres de consulta. A página XAML detecta que o redirecionamento ocorreu e pode analisar o Token de Acesso a partir da nova URL do Modo de Exibição da Web.
  9. A página Autenticação analisa o token de Acesso a partir do URI redirecionado.
  10. O aplicativo navega de volta para a página XAML original. O Token de Acesso é salvo para solicitações futuras.

Fluxo de trabalho do OAuth
Figura 2 Fluxo de trabalho do OAuth

Observação: Embora seja importante entender como o OAuth funciona, os desenvolvedores do Windows 10 têm, felizmente, uma alternativa mais simples chamada WebAuthenticationBroker. Neste artigo, uso o mecanismo OAuth de "baixo nível". Falarei sobre o WebAuthenticationBroker no próximo artigo.

Como compreender os escopos

Quando o usuário faz logon, o aplicativo precisa informar ao serviço OneDrive a gama de recursos de que ele precisará. Isso é feito por meio da especificação de escopos na URL de autenticação. No momento, o serviço dá suporte aos seguintes escopos:

  • Logon único: wl.signin.
  • Acesso offline: wl.offline_access. Permite que o aplicativo obtenha um Token de Atualização. O escopo é ignorado quando é usada a autenticação de Fluxo de Token.
  • Acesso somente leitura: onedrive.readonly. Dá ao aplicativo acesso somente leitura aos arquivos e às pastas. Se o aplicativo tentar modificar um arquivo ou carregar um novo arquivo, o serviço retornará o código de erro 403 Proibido.
  • Acesso de leitura e gravação: onedrive.readwrite. Dá ao aplicativo acesso de leitura e gravação aos arquivos e às pastas.
  • AppFolder: onedrive.appfolder. Permite que o aplicativo acesse a chamada pasta Aplicativo. Mais adiante neste artigo, fornecerei mais detalhes sobre essa pasta especial. Observe que esse escopo é concedido automaticamente quando você solicita o escopo de leitura e gravação. No entanto, a solicitação explícita da appfolder fará com que esse escopo seja mencionado na caixa de diálogo mostrada na Figura 3, o que constitui uma melhor experiência para o usuário.

Figura 3 Como iniciar a autenticação

if (!_service.CheckAuthenticate(
  async () =>
  {
    var dialog = new MessageDialog("You are authenticated!", "Success!");
    await dialog.ShowAsync();
    Frame.GoBack();
  },
  async () =>
  {
    var dialog = new MessageDialog("Problem when authenticating!", "Sorry!");
    await dialog.ShowAsync();
    Frame.GoBack();
  }))
{
  Frame.Navigate(typeof (AuthenticationPage));
};

Depois que o usuário digita suas credenciais na página da Web de autenticação, é mostrada uma caixa de diálogo que pede que ele confirme as permissões solicitadas pelo aplicativo, como é mostrado na Figura 4. O usuário pode mudar de ideia a qualquer momento e revogar algumas das permissões. Para isso, o usuário faz logon em sua conta no site do OneDrive, navega até Segurança e Privacidade e seleciona o link Gerenciar permissões em Aplicativos e Serviços. No exemplo, você sempre solicitará logon único, acesso de leitura e gravação e acesso à appfolder.

Confirmação de autenticação
Figura 4 Confirmação de autenticação

Como criar a URL inicial

A URL usada para iniciar o processo de autenticação precisa conter informações sobre o próprio aplicativo, os recursos solicitados (escopos), o modo de autenticação e o URI de redirecionamento.

O modo de autenticação pode ser Token ou Código. Neste artigo e no exemplo, usei o modo Token, o que significa que o usuário precisa confirmar o logon a cada nova inicialização do aplicativo ou após uma hora. Isso parece desagradável, mas, de fato, o usuário precisa apenas confirmar o logon pressionando o botão Sim na caixa de diálogo de autenticação, como é mostrado na Figura 4.

O URI de redirecionamento é o endereço para o qual o serviço OneDrive redirecionará o aplicativo quando o logon for bem-sucedido. Para um aplicativo Web, é o URI de uma página em seu próprio aplicativo e é configurado no centro de desenvolvimento do OneDrive, na guia Configurações de API. Porém, no caso de um aplicativo da UWP, você deve deixar esse campo vazio. Em vez disso, você usará um URI de redirecionamento predefinido:

htt://login.live.com/oauth20_desktop.srf

Como juntar todas as peças

Agora que você entende como funciona a autenticação de acordo com o OAuth, vamos ver exemplos de código. Você pode acompanhar o código no exemplo simples clicando no botão Autenticar.

Você usa uma classe chamada OneDriveService, que é implementada em uma PCL. O OneDriveService é instanciado em App.xaml.cs, e você passa a ID do Cliente para ele.

Primeiro, a MainPage pergunta ao serviço OneDrive se ele já foi autenticado, o que significa que um Token de Acesso já está presente. Você passa dois representantes para a chamada do método CheckAuthenticate: uma Ação que será chamada se a autenticação for bem-sucedida e uma Ação em caso de erro.

Se o serviço não tiver sido autenticado, a MainPage usará sua propriedade Frame para navegar até a AuthenticationPage, como é mostrado na Figura 5. Trata-se de uma página XAML simples com um Modo de Exibição da Web que ocupa toda a tela, em que o usuário inserirá seu nome de usuário e sua senha e dará a confirmação.

Figura 5 Código para a AuthenticationPage

public sealed partial class AuthenticationPage
{
  private readonly OneDriveService _service;
  public AuthenticationPage()
  {
    InitializeComponent();
    _service = ((App)Application.Current).ServiceInstance;
    Loaded += (s, e) =>
    {
      var uri = _service.GetStartUri();
      Web.Navigate(uri);
    };
    Web.NavigationCompleted += (s, e) =>
    {
      if (_service.CheckRedirectUrl(e.Uri.AbsoluteUri))
      {
        _service.ContinueGetTokens(e.Uri);
      }
    };
    Web.NavigationFailed += (s, e) =>
    {
      _service.ContinueGetTokens(null);
    };
  }
}

Quando a página é carregada, você obtém o URI de autenticação proveniente do OneDriveService:

https://login.live.com/oauth20_authorize.srf?client_id=000000004C169646&
scope=wl.signin+onedrive.readwrite+onedrive.appfolder&response_type=token&
redirect_uri=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf

Conforme explicado, esse URI contém todas as informações necessárias, como ID do Cliente, Segredo do Cliente, Escopo, URI de Redirecionamento e assim por diante.

Observe que o Modo de Exibição da Web será redirecionado algumas vezes antes que o Token de Acesso seja retornado. É por isso que você sempre deve verificar o URI de redirecionamento no evento NavigationCompleted do Modo de Exibição da Web. Quando por fim o URI oauth20_desktop.srf é detectado, o OneDriveService recupera o Token de Acesso a partir dos parâmetros de cadeia de caracteres de consulta. Informações adicionais (expiração, tipo de token, escopo, ID do usuário, etc.) serão passadas na cadeia de caracteres de consulta, mas você simplesmente as ignorará aqui. O URI de Redirecionamento com o Token de Acesso é abreviado aqui:

https://login.live.com/oauth20_desktop.srf?lc=1033#access_token=EwB4Aq1D...1iiZA%3d&
token_type=bearer&expires_in=3600&scope=wl.signin%20onedrive.readwrite%20onedrive.appfolder
%20onedrive.readonly&user_id=8e5323e8b7c7a0928d03e10811531234

Depois que o usuário for autenticado, o aplicativo poderá começar a interagir com arquivos e pastas. Neste artigo, vou me concentrar em algumas operações, mas é muito fácil estender o aplicativo para incluir serviços adicionais depois que os princípios são compreendidos.

A pasta raiz

Primeiro, vou falar sobre a pasta Raiz. Essa pasta é exclusiva no OneDrive e é o pai de cada um dos outros itens.

De acordo com a documentação do OneDrive, é possível acessar a pasta Raiz por meio da seguinte solicitação: GET /drive/root. Essa solicitação retornará uma resposta JSON, como descrito em bit.ly/1M5w4NV. A resposta JSON pode ser desserializada, e as informações que ela contém podem ser usadas para outras solicitações.

Estrutura de arquivos e pastas A esta altura, é importante entender como o sistema de arquivos é estruturado. O OneDrive usa um sistema de facetas para fornecer informações sobre arquivos e pastas. Por exemplo, um arquivo também pode ser uma Imagem e uma Foto e fornecer informações adicionais sobre o arquivo (como largura/altura da Imagem e Modelo da Câmera para a Foto). A seguinte lista mostra as facetas que estão disponíveis no momento e algumas de suas propriedades mais importantes:

  • Item (Nome, ID, url de download, referência pai, etc.)
  • Pasta (contagem de filhos)
  • Arquivo
  • Áudio (álbum, artista, taxa de bits, duração, título, etc.)
  • Imagem (largura, altura)
  • Foto (marca e modelo da câmera, data e hora em que foi tirada)
  • Vídeo (duração, taxa de bits, largura, altura)

Quando você carrega um novo arquivo para o OneDrive, ele é automaticamente analisado, e alguns metadados são adicionados. Por exemplo, um documento do Word é apenas um Arquivo. Porém, uma foto tirada com uma câmera é uma Foto e também uma Imagem, além de ser um Arquivo. Cada uma dessas facetas contém informações adicionais sobre o arquivo, como mostrado na lista.

Ao analisar o JSON obtido do serviço OneDrive, você pode mapear esses tipos para classes do C#. Inspecionando o JSON, você pode facilmente descobrir se um item é uma Pasta, um Arquivo, uma Imagem, um Vídeo e assim por diante. Por exemplo, a Figura 6 mostra um trecho da resposta JSON para a pasta Raiz. Você pode ver que a propriedade da pasta contém informações sobre a respectiva contagem de filhos. Se você estivesse obtendo informações sobre uma Foto, você veria as propriedades de imagem e foto preenchidas com informações sobre a Largura e a Altura e sobre a Marca e o Modelo da Câmera, respectivamente.

No aplicativo de exemplo fornecido com este artigo, você desserializa o JSON nas classes contidas na pasta Resposta, que são mapeadas para o sistema de facetas.

Agora que você entende como a resposta funciona, você pode facilmente acessar as informações da pasta Raiz com o código mostrado aqui:

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
  new AuthenticationHeaderValue("Bearer", AccessToken);
var uri = new Uri("https://api.onedrive.com/v1.0/drive/root");
var json = await client.GetStringAsync(uri);
var rootFolder = JsonConvert.DeserializeObject<ItemInfoResponse>(json);

Para ver o código em ação, execute o exemplo simples e pressione primeiro o botão Autenticar, e depois o botão Obter Pasta Raiz.

Como obter os filhos da pasta Como você vê na Figura 6, a resposta contém apenas metainformações sobre a pasta. Você sabe quantos filhos a pasta tem, mas precisa executar mais uma solicitação para obter a lista de filhos. Aqui, também, a documentação do OneDrive é útil e indica que você precisa solicitar um GET para /drive/items/{id_do_item}/children, como é mostrado na Figura 7.

Figura 6 Resposta JSON para a pasta raiz

{
  "createdBy": {
    "user": {
      "displayName": "Laurent Bugnion",
      "id": "fb0d8f9700498123"
    }
  },
  "createdDateTime": "2010-11-27T17:09:25.513Z",
  "id": "FB0D8F97004979CD!ABC",
  "lastModifiedBy": {
    "user": {
      "displayName": "Laurent Bugnion",
      "id": " fb0d8f9700498123"
    }
  },
  "lastModifiedDateTime": "2015-10-04T14:36:36.217Z",
  "name": "root",
  "size": 178558187077,
  "webUrl": "https://onedrive.live.com/?cid=fb0d8f9700498123",
  "folder": {
    "childCount": 18
  }
}

Figura 7 Como obter a lista de filhos

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
  new AuthenticationHeaderValue("Bearer", AccessToken);
var request = string.Format("/drive/items/{0}/children", info.Id);
var uri = new Uri(
  "https://api.onedrive.com/v1.0"
  + request);
var json = await client.GetStringAsync(uri);
var response = JsonConvert.DeserializeObject<ParseChildrenResponse>(json);
return response.Value;

Na Figura 7, o JSON é desserializado para uma classe chamada ParseChildrenResponse. Isso é novamente mapeado para a resposta JSON, que encapsula a lista de filhos em um valor nomeado de matriz JavaScript. A classe ParseChildrenResponse é mostrada na Figura 8.

Figura 8 Classe ParseChildrenResponse

public class ParseChildrenResponse
{
  public IList<ItemInfoResponse> Value
  {
    get;
    set;
  }
  [JsonProperty("@odata.nextLink")]
  public string NextLink
  {
    get;
    set;
  }
}

Como cada filho é um ItemInfoResponse, você sabe como lidar com eles e decidir se cada filho é uma pasta, um arquivo, uma foto, um arquivo de áudio, etc.

Observe que se você não quiser fazer duas chamadas para recuperar as informações da pasta e preencher a lista de filhos, também poderá usar a seguinte solicitação, que faz tudo em uma única chamada:

 

GET /drive/items/root?expand=children

Como entender a paginação Quando você acessa uma pasta com muitos filhos, a resposta enviada pelo serviço OneDrive pode estar incompleta e exigir paginação. Por padrão, o serviço só retorna uma lista de 200 filhos, no máximo. Se a pasta em que você está navegando tiver mais filhos, será adicionada à lista de filhos uma propriedade chamada "@odata.nextLink", que também pode ser vista na Figura 8. Essa propriedade contém o URI para a próxima solicitação que o aplicativo precisa fazer para acessar a próxima "página". Em um aplicativo da UWP, você pode optar por chamar o serviço imediatamente para acessar a próxima página de itens (o que funcionaria, pois as listas longas são virtualizadas) ou pode exibir um botão Mais e implementar a navegação de página no aplicativo.

Como navegar em uma subpasta Depois que você tiver a ID de uma pasta, você poderá facilmente navegar na pasta usando a seguinte solicitação:

GET /drive/items/{item-id}

Isso é ótimo quando você já tem a ID da pasta, mas às vezes você não tem essa informação. Outra sintaxe permite recuperar as informações da pasta usando seu caminho relativo à raiz, em vez disso. Você vê essa sintaxe na Figura 9.

Figura 9 Como navegar em uma subpasta pelo caminho

var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
  new AuthenticationHeaderValue("Bearer", AccessToken);
var request = string.Format("/drive/root:/{0}", path);
var uri = new Uri(
  "https://api.onedrive.com/v1.0"
  + request);
var json = await client.GetStringAsync(uri);
var result = JsonConvert.DeserializeObject<ItemInfoResponse>(json);
return result;

A pasta Aplicativo

O OneDrive tem algumas pastas especiais, como Música, Documentos, Fotos, etc. Uma das pastas especiais foi introduzida recentemente: a pasta Aplicativo. Trata-se de uma pasta especial que está disponível para o aplicativo, por exemplo, para manter configurações de roaming, carregar backups, etc. Observe que a pasta Aplicativo não é segura nem oculta de forma alguma. De fato, ela reside em uma pasta chamada Aplicativos, localizada na raiz do OneDrive do usuário. A pasta Aplicativo do aplicativo tem o mesmo nome que o aplicativo do OneDrive, conforme inserido quando você o registrou para obter a ID do Cliente. Observe que o nome do aplicativo pode estar traduzido em diferentes idiomas, com base nas configurações do aplicativo do OneDrive. O usuário tem acesso completo à pasta Aplicativo, por meio do site do OneDrive ou de qualquer aplicativo, e pode até mesmo excluir a pasta, se desejar.

Antes da introdução do conceito da pasta Aplicativo, os aplicativos salvavam (e muitos ainda salvam) suas configurações e outros arquivos na raiz do OneDrive ou em uma pasta personalizada. O uso da pasta Aplicativo para esses itens é muito mais simples e constitui uma melhor experiência para o usuário. De acordo com a documentação do OneDrive (bit.ly/1MBUkS2), a solicitação para obter as informações da pasta Aplicativo é:

GET /drive/special/approot

Como você pode ver, é fácil implementar a pasta Aplicativo em qualquer aplicativo!

Como baixar um arquivo

Que utilidade o OneDrive teria se você não pudesse carregar ou baixar arquivos? Nesta seção e na próxima, você verá como executar essa operação crucial, que é extremamente fácil.

Para baixar o conteúdo de um arquivo, o OneDrive cria uma DownloadUrl que é salva como uma propriedade na resposta do item. No entanto, observe que a URL é válida apenas por um breve período de tempo. Por isso, se as informações do arquivo tiverem sido armazenadas em cache, talvez você precise obter primeiro as informações do serviço novamente, como é mostrado na Figura 10.

Figura 10 Como baixar o conteúdo de um arquivo

public async Task<Stream> RefreshAndDownloadContent(
  ItemInfoResponse model,
  bool refreshFirst)
{
  var client = new HttpClient();
  client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", AccessToken);
  // Refresh the item's information
  if (refreshFirst)
  {
    var request = string.Format("/drive/items/{0}", model.Id);
    var uri = new Uri(
      "https://api.onedrive.com/v1.0"
      + request );
    var json = await client.GetStringAsync(uri);
    var refreshedItem =
      JsonConvert.DeserializeObject<ItemInfoResponse>(json);
    model.DownloadUrl = refreshedItem.DownloadUrl;
  }
  var response = await client.GetAsync(model.DownloadUrl);
  var stream = await response.Content.ReadAsStreamAsync();
  return stream;
}

Após acessar o fluxo de conteúdo do arquivo, você pode processá-lo localmente, salvá-lo e assim por diante. O exemplo simples pede ao usuário um local para salvar o arquivo usando um FileSavePicker.

Upload de um arquivo

Da mesma forma, o upload de um arquivo também é bastante simples depois que você acessa o fluxo do arquivo. No Windows 10, isso pode ser feito com uma instância de StorageFile, por exemplo com um FileOpenPicker. Depois que o fluxo é lido, você pode carregá-lo no OneDrive. De acordo com a documentação, você precisa usar uma operação PUT:

PUT /drive/items/{parent-id}:/{filename}:/content

O HttpClient dá suporte ao método PUT com uma instância de HttpContent. Nesse caso, como você tem o fluxo de arquivo bruto, você pode usar uma instância de StreamContent. Para salvar apenas um arquivo de texto, você pode usar um StringContent e assim por diante.

A outra informação que você precisa passar para o serviço é a ID da pasta na qual o arquivo será salvo. No exemplo simples mostrado na Figura 11, a parentId é passada para o método de upload. Observe que a operação PUT retorna um conteúdo JSON que descreve as novas informações do arquivo no OneDrive, como sua ID, a URL da Web, a URL de download, etc.

Figura 11 Upload do conteúdo de um arquivo

var content = new StreamContent(stream);
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
  new AuthenticationHeaderValue("Bearer", AccessToken);
var uri = new Uri(
  "https://api.onedrive.com/v1.0"
  + string.Format(
    "/drive/items/{0}:/{1}:/content",
    parentId,
    fileName));
var response = await client.PutAsync(uri, content);
var json = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<ItemInfoResponse>(json);
return result;

Além do upload simples descrito aqui, a API do OneDrive também oferece uploads de diversas partes e uploads retomáveis com uma sintaxe diferente. O upload simples é adequado para arquivos com menos de 100 MB. Se o arquivo for maior, consulte a documentação em bit.ly/1PB31Cn.

A última operação que vou demonstrar aqui é como obter um link de "compartilhamento" exclusivo para um item. Essa operação é conveniente para enviar um link exclusivo a um amigo por email, SMS, mídia social, etc. A Figura 12 mostra como obter essas informações, com base na ID do item. No exemplo, você pode obter um link para o arquivo que você acabou de carregar na demonstração anterior.

Figura 12 Obtenção de um link de compartilhamento

public async Task<LinkResponseInfo> GetLink(
  LinkKind kind,
  string fileId)
{
  // LinkKind id View or Edit
  var client = new HttpClient();
  client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", AccessToken);
  var request = string.Format("/drive/items/{0}/action.createLink", fileId);
  var uri = new Uri(
    "https://api.onedrive.com/v1.0"
    + request);
  var requestJson = JsonConvert.SerializeObject(
    new RequestLinkInfo
    {
      Type = kind.ToString().ToLower()
    });
  var content = new StringContent(
    requestJson,
    Encoding.UTF8,
    "application/json");
  var response = await client.PostAsync(uri, content);
  var result = JsonConvert.DeserializeObject<LinkResponseInfo>(
    await response.Content.ReadAsStringAsync());
  return result;
}

De acordo com a documentação, a solicitação é um pouco diferente das solicitações GET que você fez anteriormente, pois o serviço precisa de informações mais detalhadas. A solicitação de "link de compartilhamento" é a seguinte: POST /drive/items/{id_do_item}/action.createLink. As informações que você precisa postar para o serviço são um trecho de JSON com o tipo de link: "view" ou "edit", por exemplo: { "type": "view" }

Conclusão

Há algumas operações adicionais que não descrevo neste artigo, como excluir um arquivo, atualizar o conteúdo de um arquivo e sincronizar alterações. Porém, em geral, todas as operações seguem o mesmo padrão e podem ser realizadas usando métodos HttpClient e HTTP e JSON. Graças aos avanços na programação assíncrona no Microsoft .NET Framework, essas operações são extremamente fluidas e fáceis de implementar em qualquer estrutura com suporte, incluindo o Windows 10, mas também o WPF, o Windows Phone, o Xamarin.iOS, o Xamarin.Android e outros. Com essa facilidade de uso, não há razão para não usar a interação na nuvem em aplicativos da UWP, por exemplo para fazer backup de conteúdo ou usar um perfil móvel para configurações. No próximo artigo, você verá como a PCL recém-lançada pela equipe do OneDrive o ajudará a facilitar ainda mais essa integração.


Laurent Bugnioné diretor sênior da IdentityMine, uma das empresas líderes (e um excelente parceiro) em tecnologias Microsoft. Ele mora em Zurique, na Suíça. Seu livro de 2010, "Silverlight 4 Unleashed", publicado pela Sams, é uma continuação avançada de "Silverlight 2 Unleashed" (2008). Ele escreve para várias publicações, é MVP da Microsoft há nove anos e Diretor Regional da Microsoft há dois anos. Ele é o autor da conhecida estrutura de software livre MVVM Light para Windows, WPF, Xamarin e do popular curso de referência da Pluralsight sobre MVVM Light. Entre em contato com ele em seu blog em galasoft.ch.

Agradecemos aos seguintes especialistas técnicos pela revisão deste artigo: Corrado Cavalli (Gaia) e Ryan Gregg (Microsoft)