SharePoint 2010 & Azure: Integración de servicios mediante BCS (I)!

Una de las posibilidades que tenemos de integrar servicios WCF On-Premises o publicados en Azure es a través de los Business Connectivity Services (BCS) que facilitan el consumo de los mismos a través del correspondiente tipo de contenido externo (ECT) publicado en el catálogo de datos profesionales. A la hora de modelar estos ECTs tenemos dos posibilidades:

  • Utilizando SharePoint Desinger 2010 (SPD 2010).
  • Utilizando Visual STudio 2010.

En este primer artículo vamos a ver la primera de las posibilidades que nos permita consumir un servicio WCF On-Premise o publicado en Azure a través de un ECT creado con SPD 2010:

  • Lo primero que tenemos que hacer es disponer de un servicio ya publicado. En mi caso, el servicio a consumir tiene definida la siguiente lógica:
   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Runtime.Serialization;

   5: using System.ServiceModel;

   6: using System.ServiceModel.Web;

   7: using System.Text;

   8:  

   9: namespace CustomerService

  10: {

  11:     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.

  12:     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.

  13:     public class CustomerService : ICustomerService

  14:     {

  15:         List<Customer> lCustomersList = new List<Customer>();

  16:  

  17:         /// <summary>

  18:         /// Gets the selelected customer

  19:         /// </summary>

  20:         /// <param name="sCustomerID">ID of the selected customer</param>

  21:         /// <returns></returns>

  22:         public List<Customer> getACustomer(string sCustomerID)

  23:         {

  24:             //Generate Customer Data

  25:             generateCustomerData();

  26:  

  27:  

  28:             //Querying the customer

  29:             var qCustomer = (from c in lCustomersList

  30:                              where c.IDCustomer == sCustomerID

  31:                              select c).ToList();

  32:             //Filling the returned data           

  33:             List<Customer> lrCustomer = qCustomer;

  34:  

  35:             return lrCustomer;

  36:         }

  37:  

  38:         public List<Customer> getAllCustomers()

  39:         {

  40:             generateCustomerData();

  41:             List<Customer> lAllCustomers = new List<Customer>();

  42:  

  43:             //Querying the customers

  44:             var qCustomers = (from c in lCustomersList

  45:                               select c).ToArray();

  46:             foreach (var qc in qCustomers)

  47:             {

  48:                 Customer tCustomer = new Customer();

  49:                 tCustomer.IDCustomer = qc.IDCustomer;

  50:                 tCustomer.sCustomerName = qc.sCustomerName;

  51:                 tCustomer.sCustomerAddress = qc.sCustomerAddress;

  52:                 tCustomer.sCustomerEMail = qc.sCustomerEMail;

  53:                 tCustomer.sCustomerPhone = qc.sCustomerPhone;

  54:  

  55:                 lAllCustomers.Add(tCustomer);

  56:             }

  57:  

  58:             return lAllCustomers;

  59:         }

  60:         /// <summary>

  61:         /// This method generates customer data for the service

  62:         /// </summary>

  63:         private void generateCustomerData()

  64:         {

  65:             Customer cCustomer1 = new Customer();

  66:             cCustomer1.IDCustomer = "1";

  67:             cCustomer1.sCustomerName = "Juan Carlos González";

  68:             cCustomer1.sCustomerAddress = "C/ Camilo Alonso Vega 41 7 D 39007 Santander";

  69:             cCustomer1.sCustomerEMail = "jgonzalez@gruposodercan.es";

  70:             cCustomer1.sCustomerPhone = "647 391 399";

  71:  

  72:             lCustomersList.Add(cCustomer1);

  73:  

  74:             Customer cCustomer2 = new Customer();

  75:             cCustomer2.IDCustomer = "2";

  76:             cCustomer2.sCustomerName = "Ángel Acha";

  77:             cCustomer2.sCustomerAddress = "C/ Joaquín Costa s/n 39005 Santander";

  78:             cCustomer2.sCustomerEMail = "aacha@gruposodercan.es";

  79:             cCustomer2.sCustomerPhone = "942 760 620";

  80:  

  81:             lCustomersList.Add(cCustomer2);

  82:         }

  83:     }

  84: }

  • La clase Customer que sirve como base en los tipos devueltos por getACustomer() y getAllCustomers() tiene la siguiente implementación:
   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Web;

   5:  

   6: namespace CustomerService

   7: {

   8:     public class Customer

   9:     {

  10:         public string IDCustomer { get; set; }

  11:         public string sCustomerName{ get; set; }

  12:         public string sCustomerAddress { get; set; }

  13:         public string sCustomerEMail { get; set; }

  14:         public string sCustomerPhone { get; set; }

  15:     }

  16: }

  • Siendo ICustomerService la correspondiente interfaz en la que se definen tanto el contrato del servicio como las operaciones que implementa:
   1: using System;

   2: using System.Collections.Generic;

   3: using System.Linq;

   4: using System.Runtime.Serialization;

   5: using System.ServiceModel;

   6: using System.ServiceModel.Web;

   7: using System.Text;

   8:  

   9: namespace CustomerService

  10: {

  11:     // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.

  12:     [ServiceContract]

  13:     public interface ICustomerService

  14:     {

  15:  

  16:         [OperationContract]

  17:         List<Customer> getAllCustomers();

  18:         [OperationContract]

  19:         List<Customer> getACustomer(string sCustomerID);

  20:  

  21:       

  22:     }

  23:  

  24:  

  25:  

  26: }

  • Finalmente, el archivo web.config vital para que el servicio pueda ser consumido tiene la siguiente forma:
   1: <?xml version="1.0"?>

   2: <configuration>

   3:   <system.web>

   4:     <compilation debug="true" targetFramework="4.0" />

   5:   </system.web>

   6:     <system.serviceModel>

   7:         <services>

   8:             <service behaviorConfiguration="CustomerService.CustomerWCFServiceBehavior" name="CustomerService.CustomerService">

   9:                 <endpoint address="" binding="basicHttpBinding" contract="CustomerService.ICustomerService" />

  10:                 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

  11:             </service>

  12:         </services>

  13:         <behaviors>

  14:             <serviceBehaviors>

  15:                 <behavior name="CustomerService.CustomerWCFServiceBehavior">

  16:                     <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->

  17:                     <serviceMetadata httpGetEnabled="true"/>

  18:                     <!-- 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 -->

  19:                     <serviceDebug includeExceptionDetailInFaults="false"/>

  20:                     <useRequestHeadersForMetadataAddress>

  21:                         <defaultPorts>

  22:                             <add scheme="http" port="81"/>

  23:                             <add scheme="https" port="444"/>

  24:                         </defaultPorts>

  25:                     </useRequestHeadersForMetadataAddress>

  26:                 </behavior>

  27:             </serviceBehaviors>

  28:         </behaviors>

  29:         <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

  30:     </system.serviceModel>

  31:     <system.webServer>

  32:         <modules runAllManagedModulesForAllRequests="true"/>

  33:     </system.webServer>  

  34: </configuration>

Publicado el servicio ya sea On-Premise o en Azure, lo que necesitaremos para consumirlo en un ECT creado con SPD 2010 son las Urls del servicio y del WSDL:

image image image
  • En la configuración de la conexión al servicio WCF tendremos que especificar tanto la URL del WSDL como la del propio servicio. Especificaremos además un nombre para la conexión.
  • Como veis, la configuración difiere ligeramente en el caso de que el servicio esté publicado en Azure con respecto a si está publicado On-Premise.
  • Una vez establecida la conexión, se muestran los dos métodos disponibles que nos permitirán definir las operaciones básicas del ECT que consume el servicio.
image image image
  • Comenzamos con la operación “Leer lista” a partir del método getAllCustomers().
  • En la primera pantalla del asistentes especificamos el nombre de la operación y pulsamos “Siguiente”.
  • Pulsamos de nuevo “Siguiente”.
image image image
  • En la siguiente pantalla configuramos los parámetros de retorno de la operación. Lo más importante aquí es definir el identificador de la operación y el campo a mostrar en el selector de datos externos. Además, podremos parametrizar el nombre para mostrar en cada campo. Pulsamos Finalizar para que la primera operación quede definida.
  • Lo siguiente que haremos es definir la operación “Leer elemento”.
  • Como antes, en la primera pantalla del asistente de configuración de la operación especificamos un nombre para la misma y pulsamos “Siguiente”.
image image image
  • De nuevo definimos el identificador de la operación que en este caso es aún más importante ya que nos permite devolver una única entidad.
  • Configuramos de nuevo los parámetros de retorno y pulsamos “Finalizar”.
  • Guardamos todos los cambios realizados para que el ECT se refleje en el catálogo de datos profesionales y pulsamos la opción “Crear listas y formularios” para proceder a crear la correspondiente lista externa.
image image image
  • En la ventana de definición de la lista especificamos el nombre de la misma y si vamos a usar formularios InfoPath. Pulsamos “Aceptar” para que se cree la lista externa.
  • Navegamos al sitio de trabajo y comprobamos que en la lista creada se muestran los datos expuestos por el servicio.
  • Editamos un registro y comprobamos que se visualiza sin problemas.
image image image

Y hasta aquí llega este primer post sobre la integración de servicios mediante BCS y SPD 2010.

Publicado por

Juan Carlos González

Juan Carlos es Ingeniero de Telecomunicaciones por la Universidad de Valladolid y Diplomado en Ciencias Empresariales por la Universidad Oberta de Catalunya (UOC). Cuenta con más de 12 años de experiencia en tecnologías y plataformas de Microsoft diversas (SQL Server, Visual Studio, .NET Framework, etc.), aunque su trabajo diario gira en torno a SharePoint & Office 365. Juan Carlos es MVP de Office Servers & Services desde 2015 (anteriormente fue reconocido por Microsoft como MVP de Office 365 y MVP de SharePoint Server desde 2008 hasta 2015), coordinador del grupo de usuarios .NET de Cantabria (Nuberos.Net, www.nuberos.es), co-fundador y coordinador del Grupo de Usuarios de SharePoint de España (SUGES, www.suges.es), así como co-director de la revista gratuita en castellano sobre SharePoint CompartiMOSS (www.compartimoss.com). Hasta la fecha, ha publicado 8 libros sobre SharePoint & Office 365 y varios artículos en castellano y en inglés sobre ambas plataformas.

3 comentarios en “SharePoint 2010 & Azure: Integración de servicios mediante BCS (I)!”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *