Publicação de Serviços WCF no SharePoint

Introdução

O SharePoint 2010 trouxe novos recursos aos desenvolvedores que antes não existiam ou não eram muito simples de utilizar no SharePoint 2007. Um desses recursos era a capacidade de publicação de dados para utilização a partir de outros aplicativos.

Até então já era possível publicar web services customizados e consumir alguns web services nativos do SharePoint, mas as opções eram bem limitadas e davam bastante trabalho aos desenvolvedores. Atualmente, com o SharePoint 2010, temos várias formas de consumir dados e criar regras de negócios. As principais são: utilizar o modelo de objetos de cliente (Client Object Model), serviços padrão do SharePoint, serviço REST (ServiceData.svc) e até mesmo a API de servidor, mas essa última tem um problema, como publicá-la para aplicativos que rodam fora do servidor? A solução é através de um serviço WCF.

Se atualmente existem tantas APIs para criação de regras de negócio, por que publicar um serviço WCF customizado? A resposta é muito simples, porque desta forma encapsulamos as regras de negócios disponibilizamos somente informações necessárias para os aplicativos clientes consumirem. Em alguns casos não podemos utilizar as APIs de cliente e precisamos expor os dados já processados através de um serviço.

Exemplo: relatórios geralmente demandam grande utilização de regras de negócio. É comum os relatórios precisarem de cruzamento de informações (joins) em várias listas do SharePoint para fornecer dados consolidados ao usuário. O que fazer para obter desempenho, proteger as regras de negócio e informações e ainda ter controle de permissão? O serviço WCF roda no servidor, causando menos tráfego de rede, as regras de negócio ficam protegidas e são disponibilizadas somente para usuários com permissão. Além disso, ainda existe o fator disponibilidade, o SharePoint possui vários mecanismos de disponibilidade, sendo assim, publicando o serviço no SharePoint, automaticamente o serviço pode usufruir desses recursos.

Outra pergunta importante, por que publicar um serviço WCF no SharePoint e não criar apenas um serviço no IIS? Pelo simples fato da capacidade de abstração do endereço do site, já que estando dentro do SharePoint o objeto SPContext está criado e disponível permitindo acesso a todos os dados do site atual. Se o serviço não estivesse dentro do SharePoint todo o processo de criação dos objetos de SPSite e SPWeb seriam necessários (mais consumo de hardware), ainda tendo a obrigatoriedade de informar a url e credenciais do usuário.

Neste artigo vamos ver como criar um serviço WCF que publica todos os eventos cadastrados no site – a regra de negócio é bastante simples pois o objetivo principal é mostrar a publicação do serviço, a publicação no SharePoint e finalmente testar e validar a solução.

Criação do Serviço

A estrutura das listas que vamos utilizar no exemplo está definida na imagem 01.

Imagem 01: Estrutura das listas

No exemplo deste artigo vamos criar um projeto do tipo Empty SharePoint Project. O motivo pelo qual não utilizaremos o modelo padrão do WCF é porque o projeto do SharePoint é mais fácil de utilizar e fazer deploy diretamente a partir do Visual Studio. Aparentemente será um pouco mais difícil de configurar inicialmente, mas depois de feito será muito mais fácil de utilizar e dar manutenção.

O primeiro passo é criar o projeto, para isso é necessário abrir o Visual Studio 2010 e ir na opção “File” > “New Project…”, selecionar a categoria SharePoint >> 2010 e o template “Empty SharePoint Project”. Depois de definir os nomes clicar em OK para criar o projeto. No exemplo vamos fornecer os nomes “Servico Dados Customizado” para o projeto e “TechShare WCF” para a solução.

Imagem 02: Criação do projeto no Visual Studio 2010

Durante o processo de criação do projeto o wizard do Visual Studio 2010 irá solicitar a URL do site SharePoint em que o serviço será publicado. Informe a url e clique no botão “Validate”, se o endereço estiver correto uma mensagem de sucesso será exibida, caso contrário verifique o endereço correto e tente novamente. O tipo de deploy da solução será farm solution. Clique em “Finish” para concluir a criação do projeto.

Imagem 03: Configuração do endereço do SharePoint e tipo de solução

Para publicar o serviço no SharePoint devemos colocar os arquivos dentro do diretório ISAPI, que fica no diretório do SharePoint, mas isso não precisa ser feito manualmente. Como criamos um tipo de projeto SharePoint Empty Project, o Visual Studio irá fazer essa tarefa por nós, basta adicionar o mapeamento para a pasta, como nas imagens 04 e 05.

Imagem 04: Adicionando a pasta mapeada do SharePoint

Imagem 05: Adicionando o mapeamento para a pasta ISAPI

Após o mapeamento feito vamos criar a pasta que irá conter o nosso serviço, no caso a pasta “ServicoDadosCustomizado” que irá ficar dentro da pasta ISAPI.

Imagem 06: Criação da ServicoDadosCustomizado

O próximo passo é adicionar as referências ao projeto, é necessário adicionar todas as referências abaixo:

· System.ServiceModel.dll – C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\System.ServiceModel.dll

· Microsoft.SharePoint.Client.ServerRuntime.dll – c:\Windows\assembly\GAC_MSIL\Microsoft.SharePoint.Client.ServerRuntime\_

14.0.0.0__71e9bce111e9429c\Microsoft.SharePoint.Client.ServerRuntime.dll

· System.Runtime.Serialization para poder ter os atributos [DataContract] e [DataMember] nas classes do serviço

· Microsoft.SharePoint.Linq – C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.SharePoint.Linq.dll

Com as referências feitas vamos criar a interface do serviço, para isso adicione um novo item do tipo interface no projeto com o nome IServicoEventos. Foram criados dois métodos: ObterTodosEventos, que retorna a lista de todos os eventos cadastrados no site e o método Teste, que retorna uma string de teste. A listagem 01 possui o código fonte da interface.

using System;

using System.ServiceModel;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Servico_Dados_Customizado

{

    [ServiceContract]

    public interface IServicoEventos

    {

        [OperationContract]

        List<Evento> ObterTodosEventos();

        [OperationContract]

        string Teste();

    }

}

Listagem 01: Implementação da interface IServicoEventos.cs

A classe de Evento contará apenas com duas propriedades: título da palestra e o nome do palestrante, conforme listagem 02.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.Serialization;

namespace Servico_Dados_Customizado

{

    [DataContract]

    public class Evento

    {

        [DataMember]

        public string Titulo { get; set; }

        [DataMember]

        public string Palestrante { get; set; }

    }

}

Listagem 02: Implementação da classe Evento.cs

A implementação da classe do serviço é onde as regras de negócio serão criadas, mais detalhes na listagem 03.

using System;

using System.ServiceModel;

using System.ServiceModel.Activation;

using Microsoft.SharePoint;

using Microsoft.SharePoint.Client.Services;

using System.Linq;

using System.Collections.Generic;

namespace Servico_Dados_Customizado

{

    // Atributos obrigatórios para a publicação do serviço o SharePoint, com a utilização deles não precisamos ter arquivos de configuração para o serviço

    [BasicHttpBindingServiceMetadataExchangeEndpointAttribute]

    [AspNetCompatibilityRequirementsAttribute(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

    public class ServicoEventos : IServicoEventos

    {

        public List<Evento> ObterTodosEventos()

        {

            // A partir do contexto atual de execução do site (site corrente e autenticação com o usuário atual) a lista eventos é obtida.

            SPList listaPalestrantes = SPContext.Current.Web.Lists[“Eventos”];

            List<Evento> listaEventos = new List<Evento>();

            SPFieldLookupValue palestrante;

            foreach (SPListItem item in listaPalestrantes.Items)

           {

               // O campo palestrante é do tipo consulta (lookup) que referencia a lista Palestrantes. A melhor maneira de obter o seu valor

               // é utilizando a classe SPFieldLookupValue informando qual é o valor que se deseja converter.

               palestrante = new SPFieldLookupValue(item[“Palestrante”].ToString());

                // Cria um novo objeto Evento, inicializa as propriedades e adiciona à coleção

               listaEventos.Add(new Evento()

               {

                   Palestrante = palestrante.LookupValue,

                   Titulo = item[“Title”].ToString()

               });

           }

           return listaEventos;

        }

        public string Teste()

        {

            return “Teste”;

        }

    }

}

Listagem 03: Implementação da classe de negócio ServicoEventos.cs

Agora que todas as classes estão implementadas é necessário criar o arquivo do serviço. Esse é o arquivo que será utilizado na URL para acessar o serviço. Como o template de projeto não é do tipo WCF não existe a opção de adicionar um novo item do tipo serviço, por causa disso vamos adicionar um item do tipo text file (txt) e renomeá-lo para Servico.svc. O arquivo deve ser criado dentro da pasta ServicoDadosCustomizado, conforme a imagem 06. A listagem 04 mostra o conteúdo do arquivo, o item mais importante é o “Service”, que deverá ser alterado conforme a nomenclatura utilizada no projeto. Se os nomes utilizados no projeto forem iguais ao deste artigo, apenas a propriedade PublicKeyToken precisa ser alterada, caso o nome do projeto, namespace ou classe tenham sido alterados, fazer os ajustes necessários. Para descobrir o PublicKeyToken é necessário fazer o deploy da solução conforme a imagem 07, depois ir até o diretório C:\Windows\Assembly e procurar pelo assembly Servico_Dados_Customizado, a coluna “Public Key Token” terá o valor que deve ser colocado na chave PublicKeyToken.

<%@ServiceHost

Language=”C#”

Factory=”Microsoft.SharePoint.Client.Services.MultipleBaseAddressBasicHttpBindingSe_

rviceHostFactory,Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”

Service=”Servico_Dados_Customizado.ServicoEventos, Servico_Dados_Customizado, Version=1.0.0.0, Culture=neutral, PublicKeyToken=781147ec3b4f8a7f”

%>

Listagem 04: Servico.svc

Imagem 07: Deploy através do Visual Studio 2010

Imagem 08: Global Assemly Cache (GAC)

Testando o Serviço

O serviço foi publicado no diretório do SharePoint, dentro da pasta ISAPI (Imagem 05 e 06). Essa pasta tem um mapeamento automático em todos os sites do SharePoint – isso é um recurso do SharePoint – sob o endereço /vti_bin (ISAPI no projeto é igual a _vti_bin na URL), ou seja, http://evento.azeroth.com/_vti_bin, a partir daí posso informar o endereço completo do serviço: http://evento.azeroth.com/_vti_bin/ServicoDadosCustomizado/Servico.svc/MEX. Ao fazer isso a imagem 08 será exibida.

Imagem 09: Teste do serviço utilizando o navegador

Consumindo o Serviço em um Aplicativo

Agora que o serviço está pronto vamos criar um programa console para testá-lo. A primeira coisa a fazer é criar o projeto do tipo Console Application, como na imagem 10.

Imagem 10: Criação do projeto console

O próximo passo é adicionar a referência ao serviço, conforme imagens 11 e 12.

Imagem 11: Adicionando a referência ao serviço

Imagem 12: Adicionando a referência ao serviço

O arquivo Program.cs, que é gerado automaticamente na criação do projeto, colocar o código para chamar o serviço de eventos e exibir na tela o resultado. A listagem 05 mostra isso com detalhe.

using System;

using System.Collections.Generic;

using System.Text;

using System.ServiceModel;

namespace Consumidor_de_Serviço

{

    class Program

    {

        static void Main(string[] args)

        {

            // Faz as configurações do bind com o serviço WCF

            BasicHttpBinding binding = new BasicHttpBinding();

            binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;

            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;

            // Define o endereço do endpoint

            EndpointAddress endpoint = new EndpointAddress(@”http://evento.azeroth.com/_vti_bin/ServicoDadosCustomizado/Servico.svc&#8221;);

            ServicoEventos.ServicoEventosClient proxy = new ServicoEventos.ServicoEventosClient(binding, endpoint);

            proxy.ClientCredentials.Windows.AllowedImpersonationLevel =

System.Security.Principal.TokenImpersonationLevel.Impersonation;

            // Executa o método do serviço

            ServicoEventos.Evento[] eventos = proxy.ObterTodosEventos();

            // Para cada evento uma linha contendo o nome do evento e palestrante será exibida

            string texto = “O palestrante {0} irá no evento {1}”;

            foreach (ServicoEventos.Evento evento in eventos)

            {

                Console.WriteLine(string.Format(texto, evento.Palestrante, evento.Titulo));

            }

            Console.Read();

        }

    }

}

Listagem 05: Implementação do programa de teste

Ao executar o programa, o resultado será parecido com a imagem 13, conforme os dados existentes na lista de eventos e palestrantes.

Imagem 13: Resultado da execução do programa

Considerações Finais

Neste artigo vimos uma opção de desenvolvimento de soluções para SharePoint onde as regras de negócio ficam hospedadas dentro do SharePoint para serem consumidas por outros aplicativos, essa solução é baseada na publicação de serviços WCF no SharePoint. As principais vantagens dessa solução são que os serviços WCF contém o objeto de contexto do SharePoint, isolamento da regra de negócio, segurança e disponibilidade.

Cada projeto SharePoint possui requisitos diferentes e singulares. Isto faz com que cada projeto seja um projeto diferente e com necessidades diferentes. Como existem várias APIs e maneiras diferentes de resolver as necessidades de negócio é sempre muito importante planejar com cuidado a solução. A solução apresentada não substitui o uso das APIs de cliente, ela trabalha em conjunto para fornecer soluções cada vez mais ricas e maduras.

Referências

· Custom WCF Services in SharePoint 2010

http://www.sharepointbits.com/blog/custom-wcf-services-in-sharepoint-2010.html

· How Deploy a WCF Service To SharePoint 2010

http://www.chaholl.com/archive/2010/03/10/how-deploy-a-wcf-service-to-sharepoint-2010.aspx

· Customizing WCF Services in SharePoint 2010

http://answers.oreilly.com/topic/1404-how-to-customize-wcf-services-in-sharepoint-2010/

· WCF and SharePoint: context != context

http://blog.mastykarz.nl/wcf-sharepoint-context/

· WCF Services in SharePoint Foundation 2010

http://msdn.microsoft.com/en-us/library/ff521586.aspx

· Creating a Custom WCF Service in SharePoint Foundation

http://msdn.microsoft.com/en-us/library/ff521581.aspx

· WCF Services in SharePoint Foundation 2010

http://msdn.microsoft.com/en-us/library/ff521586.aspx

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: