O OData baseia-se em protocolos standard para oferecer serviços de dados interoperáveis com aplicações que não usam a framework .Net. Como é baseado em URIs standard para aceder aos dados, podemos aceder e alterar dados usando a semantica REST (Representational State Transfer), como sejam os verbos GET, PUT, POST e DELETE. Isto possibilita a utilização destes serviços a partir de qualquer cliente que possa aceder a dados transmitidos sobre protocolo HTTP standard.
Um serviço OData pode representar dados no formato Atom, JSON (JavaScript Object Notation) e XML, sendo que Atom é o formato por omissão.
O formato dos dados é especificado no header do pedido HTTP.
É bastante fácil acrescentar serviços customizados a serviços de dados WCF, através de Service Operations.
Service Operations são métodos disponibilizados num servidor e que podem ser acedidos por URIs da mesma forma que os recursos de dados vistos anteriormente.
Service Operations podem também usar expressões de query para filtrar, ordenar e paginar os dados resultado da invocação de uma operação.
Vamos, neste artigo, ver como podemos disponibilizar Service Operations, em formato OData, SOAP e JSON.
Começamos por abrir o projeto criado no artigo anterior, e criar uma Domain Service Class:
Selecionamos as caixas de Enable client access que irá possibilitar o acesso a aplicações cliente, e de Expose OData endpoint, que irá criar um ponto de acesso OData para os Domain services.
Deve-nos aparecer a classe DBcontext (do Entity Framework) e selecionando-a aparecem as entidades do modelo de domínio. Selecionamos as entidades pretendidas e assinalamos a caixa relativa a enable editing, para que sejam gerados serviços de CRUD e não apenas de consulta.
Para utilizar o modelo Entity Framework model com serviços WCF RIA Services, é preciso converte-lo para um modelo baseado em 'ObjectContext'. Isto pode ser feito através dos seguintes passos:
- Abrir o entity model no designer (diagrama)
- (Se necessário clicar no espaço em branco do diagrama para garantir que nenhum objeto dentro do modelo está selecionado)
- Na janela de propriedades do modelo de entidades (diagrama) alterar a "Code Generation Strategy" de "None" para "Default"
- Apagar os dois ficheiros ".tt" adjacentes ao modelo, assumindo que estes não foram modificados pelo utilizador, correspondendo às versões originalmente geradas. Se estes ficheiros foram modificados, então as alterações perder-se-ão.
- Fazer o "Rebuild" do projeto.
Após estes passos será possível selecionar a classe de Contexto do modelo de entidades do Entity Framework na lista de 'Available context classes'. O efeito co-lateral de estas alterações doi ter convertido o entity model de um modelo Entity Framework baseado em DbContext para um modelo baseado em ObjectContext.
(fonte: http://support.microsoft.com/kb/2745294)
A criação da Domain Service Class (RentACarDomainService), produz um ficheiro RentACarDomainService.cs:
...
[EnableClientAccess()]
public class RentACarDomainService : LinqToEntitiesDomainService<Rent_a_CarEntities>
{
// TODO:
// Consider constraining the results of your query method. If you need additional input you can
// add parameters to this method or create additional query methods with different names.
// To support paging you will need to add ordering to the 'Cars' query.
[Query(IsDefault = true)]
public IQueryable<Car> GetCars()
{
return this.ObjectContext.Cars;
}
public void InsertCar(Car car)
{
if ((car.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(car, EntityState.Added);
}
else
{
this.ObjectContext.Cars.AddObject(car);
}
}
...
São também criadas algumas linhas no ficheiro Web.config:
...
<configSections>
...
<sectionGroup name="system.serviceModel">
<section name="domainServices" type="System.ServiceModel.DomainServices.Hosting.DomainServicesSection, System.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="MachineToApplication" requirePermission="false" />
</sectionGroup>
</configSections>
...
<system.serviceModel>
<domainServices>
<endpoints>
<add name="OData" type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</endpoints>
</domainServices>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
...
De notar o elemento sectionGroup, com a definição de uma secção domainServices e do elemento domainServices, onde passou a estar definido um endpoint OData para os Domain Services criados.
Os domain services podem ser acedidos no endpoint OData através do endereço:
http://localhost:25408/WcfRentACarService/WcfRentACarService-RentACarDomainService.svc/OData/
onde, localhost:25408 correspondem ao nome do servidor e porta onde estão disponibilizados os serviços,
WcfRentACarService é o nome do projeto,
WcfRentACarService-RentACarDomainService.svc fornece o acesso aos serviços definidos na domain class WcfRentACarService.RentACarDomainService e por fim /OData/ é o endpoint.
O endereço http://localhost:25408/WcfRentACarService/WcfRentACarService-RentACarDomainService.svc/OData/CarSet
devolve-nos todos os carros (cars) da tabela respetiva na BD.
Na versão atual, o OData apenas dá acesso aos métodos de Query do domain service.
Para acedermos aos restantes métodos / serviços temos que aceder por SOAP ou JSON.
Para isso, precisamos de criar endpoints SOAP e JSON.
Precisamos de ter instalado o Package RIA Services SOAP and JSON Endpoints:
Para além disso, na secção endpoints do Web.config deverão ter aparecido mais dois endpoints, respetivamente SOAP e JSON:
<endpoints>
<add name="OData" type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="soap" type="Microsoft.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="json" type="Microsoft.ServiceModel.DomainServices.Hosting.JsonEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</endpoints>
O acesso aos serviços por JSON faz-se por:
http://localhost:25408/WcfRentACarService/WcfRentACarService-RentACarDomainService.svc/json/GetCars
onde json é o endpoint e GetCars é o nome de um dos domain services disponibilizados.
No próximo artigo veremos como invocar estes serviços numa página HTML usando Javascript e/ou JQuery.
Referências:
- http://msdn.microsoft.com/en-us/library/cc668794(v=vs.110).aspx
- http://msdn.microsoft.com/en-us/library/ee707373(v=vs.91).aspx
- http://msdn.microsoft.com/en-us/library/cc668792(v=vs.110).aspx
- http://www.odata.org/documentation/operations/
- http://www.odata.org/documentation/odata-v2-documentation/json-format/
- http://support.microsoft.com/kb/2745294
- http://blogs.msdn.com/b/deepm/archive/2010/05/14/silverlight-tv-episode-26-exposing-soap-json-and-odata-endpoints-from-ria-services.aspx
Artigos relacionados:
Sem comentários:
Enviar um comentário