Este artigo foi traduzido por máquina.

Pontos de dados

Criar e consumir OData formato JSON

Julie Lerman

Baixe o código de exemplo

Julie LermanNa minha coluna de junho, "Dados vincular OData em Web Apps com Knockout.js" (msdn.microsoft.com/magazine/jj133816), eu tinha algum divertimento com Knockout.js e OData. Como eu aprendi como dados vincular Knockout para os resultados do serviço OData, também descobri mais sobre OData e JSON do que eu tinha anteriormente conhecido. Na coluna deste mês, eu vou mudar o meu foco para consumir JSON de OData e criando JSON-friendly WCF Data Services.

Mostrarei como consumir JSON diretamente do JavaScript, como tirar proveito do SDK JavaScript OData (chamado datajs) e como garantir a sua alimentação é flexível o suficiente para dar suporte a qualquer estilo de codificação do cliente que vai precisar de JSON.

OData é uma especificação para garantir que os consumidores de serviço de dados podem contar com uma experiência consistente de serviços que consomem. Uma das regras da especificação é que OData resultados são produzidos por padrão em formato de átomo (que é uma forma específica de formatação XML), e que ele também pode produzir resultados no formato JSON.

Como a especificação de OData evolui, introduz novos recursos que podem ser usuários de seu serviço para aproveitar. Depois de discutir as várias maneiras de consumir e criar JSON feeds OData, eu vou ter certeza que você entende como futuras alterações à vontade spec OData afetam OData e o que você pode fazer hoje para estar preparado. Vou começar por expor a um cliente com o seguinte esquema no meu serviço:

public class Customer
{
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string AccountNumber { get; set; }
}

Por padrão, um resultado de cliente do meu serviço seria dados ATOM e olhar (como formatado por um browser), como mostrado na Figura 1.

Results as ATOM
Figura 1 resultados como átomo

O mesmo resultado de saída como JSON seria:

{"d":[
{"__metadata":{"id":"http://localhost:43447/DataService.svc/Customers(1)",
               "uri":"http://localhost:43447/DataService.svc/Customers(1)",
               "type":"DataAccessMSDNJuly2012.Customer"},
  "Id":1,
  "FirstName":"Julie",
  "LastName":"Lerman",
  "AccountNumber":"A123"}
]}

Se você estiver trabalhando com os resultados brutos de ATOM ou JSON, o formato da saída pode fazer uma grande diferença na facilidade de codificação. Por exemplo, se você está consumindo o feed em JavaScript, é muito mais fácil trabalhar diretamente com um objeto JSON que tem que analisar o XML.

Há duas maneiras para garantir que seus resultados Voltar no formato JSON: Você pode especificar application/json no cabeçalho da solicitação, ou você pode adicionar um parâmetro de consulta OData. Ao compor solicitações em Fiddler para testar, é muito fácil de adicionar um cabeçalho, como mostrado na Figura 2.

Specifying JSON in the Request Header
Figura 2 especificando JSON no cabeçalho de solicitação

Você também pode adicionar um cabeçalho em JQuery quando você constrói o seu pedido, mas graças a um par de outras opções, você não tem que ir para esse comprimento. Uma dessas opções é usar o datajs, a biblioteca de JavaScript para OData, que prevê a codificação contra OData também de muitos outros benefícios. A outra opção é usar o parâmetro de consulta OData, $format.

Obter JSON por padrão com datajs

Você pode baixar o datajs de datajs.codeplex.com. No momento da escrita, a versão atual é 1.0.3.

Se você estiver usando Visual Studio, você pode adicionar datajs diretamente para seu projeto usando o Gerenciador de pacotes NuGet. NuGet irá adicionar uma pasta de scripts para seu projeto e colocar a versão atual do datajs (datajs-1.0.3.js) e seus arquivos de script de min relacionados nessa pasta.

A biblioteca de script fornece uma classe chamada OData que facilita a leitura e gravação de feeds OData-compatível e fornece outros recursos. Embora você pode facilmente inserir um cabeçalho em solicitação através da função de OData.read, não é necessário. Por padrão, o datajs adicionará automaticamente o cabeçalho porque se você estiver usando esta biblioteca, é provável que você quer JSON.

Aqui está algum JavaScript que chama OData.read, passa no Uri que representa a minha consulta de serviço de dados e especifica o que fazer com os resultados (neste caso, estou armazenando os resultados em uma variável chamada cliente):

<script src="Scripts/datajs-1.0.2.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
  var customer;
  OData.read({ requestUri:"http://localhost:43447/DataService.svc/Customers?$top=1"
             },
             function (data, response) {
               customer = data.results[0];
             },
             function (err) {
               alert("Error occurred: " + err.message);
             });
</script>

Como depurar através deste script, eu posso ver que o resultado da consulta é um objeto, como mostrado na Figura 3.

Debug View of JSON Result
Figura 3 depuração de modo de exibição de resultado JSON

Com Fiddler em execução para capturar o tráfego HTTP, vejo que o cabeçalho de Accept, especificando application/json, fazia parte do pedido.

Se você é um desenvolvedor PHP, você deve verificar se a biblioteca relacionada, OData SDK para PHP (odataphp.codeplex.com). Tal como a biblioteca de datajs para desenvolvedores de JavaScript, o SDK do PHP garante que os resultados são relevantes. Mas, neste caso, fá-lo, solicitando o formato ATOM e, em seguida, materializar os dados resultantes do átomo em objetos do PHP.

Solicitando o JSON com o formato $ parâmetro

Nem todos que precisam de JSON estará usando a biblioteca de datajs. Mas isso não significa, necessariamente, que você tem que usar o cabeçalho de solicitação para pedir em JSON. A especificação de OData também tem um parâmetro de consulta, $format, que aceita o json como um dos seus valores.

Aqui é o Uri pela que solicita JSON diretamente:

http://localhost:43447/DataService.svc/Customers (1)?$ format = json

Você pode adicionar o parâmetro de formato de $ para qualquer consulta. Aqui eu estou combinando a solicitação do formato com um filtro:

http://localhost:43447/DataService.svc/Customers?$Filter=FirstName eq 'Julie' &$ format = json

Forçando um serviço de dados para homenagear o formato $ parâmetro

Ainda usando esse parâmetro de formato para solicitar que JSON é parte da especificação do OData, nem todo serviço de dados sabe como processar o parâmetro.Na verdade, quando você criar um serviço WCF de dados do .net, ele retorna átomo por padrão.Assim, enquanto o serviço irá aceitar o formato $= parâmetro de json, ele retornará ainda ATOM na resposta.Mas alguns desenvolvedores da equipe OData compartilhou uma solução simples (disponível em archive.msdn.microsoft.com/DataServicesJSONP) você pode adicionar em seu aplicativo que permite que WCF Data Services para processar o $Formatar comando e retorno JSON.

A extensão é fornecida sob a forma de uma classe chamada JSONPSupportInspector e um atributo chamado JSONP­SupportBehavior.Ambas as classes utilizam lógica de System.Component­modelo.Você pode adicionar as classes diretamente ao seu projeto ou criar um assembly de fazer referência.Depois que seu serviço WCF de dados tem acesso a essas classes, tudo o que você precisa fazer é adicionar o atributo JSONPSupportBehavior para a classe de serviço, da seguinte forma:

[JSONPSupportBehavior]
public class DataService : DataService<SalesContext>
{
  public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("Customers", EntitySetRights.All);
    config.SetEntitySetAccessRule("Orders", EntitySetRights.All);
  }

Com este atributo no lugar, meu serviço responderá no formato $= json parâmetro quando eu adicioná-lo na consulta e meu serviço retornará JSON.

Estou escrevendo esta coluna na esteira do lançamento abril de 2012 do WCF Data Services 5, que ainda exige que você adicionar explicitamente o apoio JSONP para seus serviços de dados. Se você gostaria de ver este envolto na API de WCF Data Services no futuro, você pode adicionar uma votação para sugestões de recurso da equipe UserVoice no bit.ly/ImeTQt.

Suporte a JSON e OData versões

A especificação de OData está atualmente na versão 2 e evoluindo. Trabalho na versão 3 está em andamento, com documentação beta já está disponível em OData.org. Por padrão, o WCF Data Services se destina a versão 1. Infelizmente, o padrão não vai funcionar se você quiser usar um recurso de versão 2 de OData, como paginação do lado do servidor, que está disponível no WCF Data Services. Eu adicionei a configuração de SetEntitySetPageSize para o meu serviço para demonstrar:

public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("Customers", EntitySetRights.All);
    config.SetEntitySetAccessRule("Orders", EntitySetRights.All);
    config.SetEntitySetPageSize("Customers", 3);
  }

Com esse recurso de versão 2 no lugar, o serviço irá lançar uma exceção e dizer-lhe que você tem que especificar o MaxProtocolVersion maior do que a versão 1. Aqui é o erro associado com a configuração SetEntitySetPageSize:

"Paginação do lado do servidor não pode ser usado quando a MaxProtocol­versão do serviço de dados é definido como DataServiceProtocolVersion.V1."

Para corrigir o problema, é fácil o suficiente definir a versão do código de serviço:

public static void InitializeService(DataSeviceConfiguration config)
  {
    config.SetEntitySetAccessRule("Customers", EntitySetRights.All);
    config.SetEntitySetAccessRule("Orders", EntitySetRights.All);
    config.SetEntitySetPageSize("Customers", 3);
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
  }

E, neste caso, é ainda possível solicitar a saída JSON no cabeçalho da solicitação ou usando o parâmetro de formato de $ no Uri.

No entanto, você poderá projetar seu serviço seja compatível com o avanço, definindo a MaxProtocolVersion para DataServiceProtocol­Version.V3. Mas na versão 3, estará alterando o formato JSON para um formato de saída mais simples, chamado JSON luz (bit.ly/JrM6RQ). Isso pode ser um grande problema, se seu aplicativo cliente não está esperando o formato JSON simplificado. Da perspectiva do aplicativo de consumo, parece que o pedido de JSON foi ignorado porque o átomo será devolvido e não de JSON.

Isso é porque seu cliente deve solicitar o formato mais detalhado ou explicitamente especificar a versão do OData para destino. Sem qualquer uma destas regras satisfeitos, o serviço retornará o átomo. Portanto, você deve fazer uma ou outra das tarefas necessárias para obter resultados JSON, quando o serviço estiver definido para a versão 3.

Aqui é um cabeçalho de solicitação modificado para solicitar especificamente o formato detalhado de JSON:

Aceite: application/json; odata = verbose

E aqui está um exemplo de cabeçalho com um pedido específico que a resposta de OData usa formatação versão 2:

Aceite: application/json

MaxDataServiceVersion: 2.0

Se você estiver usando o formato $= json parâmetro na consulta em vez de solicitar JSON no cabeçalho? Novamente, o serviço não vai compreender a solicitação e você obterá um erro informando que o tipo MIME não é suportado. Neste caso, você deve incluir o MaxDataServiceVersion no seu cabeçalho de solicitação.

No entanto, se você estiver usando datajs, você não precisa se preocupar. Começando com a versão 1.0.3, a biblioteca está ciente da necessidade das informações de versão e fornece-lo em suas solicitações. Neste lugar, o serviço está pronto para OData versão 3 e os consumidores têm a flexibilidade para solicitar qualquer que seja o formato de versão que eles gostam.

JSON no Pipeline OData

Graças a seu formato aerodinâmico, o JSON é um formato cada vez mais importante para os desenvolvedores. Você deve se lembrar que até mesmo alguns dos bancos de dados do novo documento eu escrevi sobre a coluna pontos de dados de novembro de 2011, "o que diabos são bancos de dados do documento?" (MSDN.Microsoft.com/Magazine/hh547103), armazenamento de dados usando JSON ou alguma torção em JSON.

Se você verificar a coluna de pontos de dados do mês passado, você encontrará exemplos de leitura e gravação para serviços de dados usando JSON e Knockout.js.

Como nós nos movemos uma idade quando mais e mais aplicações estiverem desconectadas, você vai apreciar a capacidade de consumir OData como JSON (em um detalhado ou o novo formato mais eficiente). E se você estiver criando serviços, seus consumidores certamente serei gratos se você pode torná-lo fácil para que possam acessar os seus dados desta forma.

Julie Lerman é um Microsoft MVP, consultor que vive nas montanhas de Vermont e mentor de .net. Você pode encontrar a sua apresentação sobre acesso a dados e outros tópicos de Microsoft .net em grupos de usuários e conferências ao redor do mundo. She blogs em thedatafarm.com e é autor de "Programação Entity Framework" (o ' Reilly Media, 2010) e "Programação Entity Framework: Código do primeiro"(o ' Reilly Media, 2011). Siga ela no Twitter em Twitter.com /julielerman..

Graças ao especialista técnico seguir para revisar este artigo: Alejandro Trigo