sábado, 30 de noviembre de 2013

CRUD BÁSICO CON WCF

CRUD BÁSICO CON WCF DATA SERVICES


En este artículo vamos a ver cómo usar WCF Data Services para interactuar con nuestra base de datos mediante REST, para esto vamos a realizar un formulario de CRUD básico y seguiremos los siguientes pasos:

1.       Crear aplicación Asp.net
2.       Crear modelo de datos con Entity Framework
3.       Crear WCF Data Service
4.       Configurar WCF Data Service para acceso a nuestras entidades.
5.       Interactuar  con nuestro servicio desde una aplicación asp.net

¿Qué es WCF Data Services?
También conocido como ADO.NET data services, es un componente del .net Framework que permite crear servicios web usando ODATA (Open Data Protocol), para exponer y consumir datos en la web mediante REST, ODATA expone los datos como recursos que son accesibles y modificados a través de URIs, usando los verbos HTTP GET(Consultar), PUT(Modificar), POST(Ingresar) y DELETE(Eliminar).

Creando nuestro modelo de datos con la DB ejemplo Northwind.
Antes que nada para crear el modelo debemos tener la base de datos Northwind en nuestra instancia de SQl Server, dichas base de datos se adjunta en este artículo para que se sea descargada y restaurada. Una vez tengamos esta DB, en nuestro proyecto web hacemos click derecho, agregar un nuevo elemento y seleccionamos, ADO:NET Entity Data Model.




Luego configuramos la conexión con la base de datos:



Y seleccionamos las tablas que necesitemos de nuestra base de datos.



Creando nuestro WCF Data Service.
Ahora que tenemos creado nuestro modelos de datos, procedemos a crear nuestro servicio de datos, para esto hacemos clic derecho, agregar nuevo elemento, y elegimos Servicio de datos WCF.



Enseguida nos crea nuestro Data service, y nos indica que debemos especificar el origen de datos y configurar los permisos para las entidades que vamos a exponer en el servicio.

public class WcfDataService1 : DataService/* TODO: escriba aquí el nombre de clase del origen de datos */ >
{
// Se llama a este método una única vez para inicializar directivas aplicables a todo el ámbito del servicio.
        public static void InitializeService(DataServiceConfiguration config)
        {
// TODO: establezca reglas para indicar qué operaciones de servicio y conjuntos de entidades son visibles, actualizables, etc.
            // Ejemplos:
// config.SetEntitySetAccessRule("MiConjuntoDeEntidades", EntitySetRights.AllRead);
// config.SetServiceOperationAccessRule("MiOperaciónDeServicio", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
}



En nuestro caso el origen de datos es NorthwindEntities que hace referencia al modelo que creamos con entity Framework, y vamos a especificar permisos de crear, leer, actualizar y eliminar datos en la tabla Customers de nuestra DB, la configuración del servicio nos queda así:

public class NorttwindAccess : DataService<NorthwindEntities>
{
// Se llama a este método una única vez para inicializar directivas aplicables a todo el ámbito del servicio.
        public static void InitializeService(DataServiceConfiguration config)
        {
// TODO: establezca reglas para indicar qué operaciones de servicio y conjuntos de entidades son visibles, actualizables, etc.
            // Ejemplos:
// config.SetEntitySetAccessRule("MiConjuntoDeEntidades", EntitySetRights.AllRead);
// config.SetServiceOperationAccessRule("MiOperaciónDeServicio", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

            config.SetEntitySetAccessRule("Customers"EntitySetRights.All);
            config.UseVerboseErrors = true;
        }
}

Cabe resaltar la configuración de UseVerboseErrors en True, esto para lograr obtener el detalle completo de la excepción desde el web services, en caso de que ocurra algún error.

Ahora tenemos configurado nuestro servicio de datos, lo podemos probar ingresando a la URL http://localhost:1995/NorttwindAccess.svc donde NorttwindAccess es el nombre de nuestro servicio.

  

Nos muestra las tablas a la cuales otorgamos permisos, en este caso solo la tabla Customeres.
También podemos hacer cualquier query a través de la URI de nuestro servicio, algunos ejemplos a continuación:

·         Seleccionar todos los registros de la tabla Customers:

·         Seleccionar los registros donde el Campo CustomerID sea igual a “ALFKI”:
·         Seleccionar todos los registros de la tabla Customers ordenados por el campo ContactNAme:

·         Seleccionar todos los registros de la tabla Customers donde el campo ContactName termine en “no”:
http://localhost:1995/NorttwindAccess.svc/Customers?$filter=endswith(ContactName, 'no')

·         Seleccionar los campos CustomerID y ContactName de la tabla Customers:

Estos son algunos ejemplos de los tantos que se pueden hacer.


Ahora procedemos a referenciar nuestro nuevo servicio de datos a nuestra aplicación web asp.net, para poder interactuar con él.



Una vez tenemos nuestro servicio de datos referenciado podemos interactuar con el desde nuestra aplicación.

En nuestro ejemplo vamos a crear un CRUD básico para la tabla Customers, visualmente es de la siguiente forma:




Para poblar el GridView con todos los Clientes, creamos el siguiente método el cual será invocado en el evento Load de nuestra página.


private void LlenarGrid()
{
var serv = new NorthwindService.NorthwindEntities(newUri("http://localhost:1995/NorttwindAccess.svc"));

       var clientes = (from c in serv.Customers
                       orderby c.ContactName
                       select c).ToList();

       this.gvCustomers.DataSource = clientes;
       this.gvCustomers.DataBind();
}


Observemos que inicializamos nuestro modelo de datos a partir de nuestro servicios de datos, y sobre el podemos ejecutar cualquier consulta linq to entities, en este caso obtenemos  todos los registros de la tabla Customers y cargamos el GridView con los resultados.


Ahora para eliminar un registro de la tabla Customers, en el vento gvCustomers_RowDeleting
De nuestro gridView asignamos el siguiente fragmento de código:


try
{
string strID = this.gvCustomers.Rows[e.RowIndex].Cells[0].Text;
var serv = new NorthwindService.NorthwindEntities(newUri("http://localhost:1995/NorttwindAccess.svc"));
       NorthwindService.Customers eliminarCliente = (from c in serv.Customers
                                                    where c.CustomerID.Equals(strID)
                                               select c).Single();
       serv.DeleteObject(eliminarCliente);
       serv.SaveChanges();
       this.lblError.Text = "El cliente se elimino correctamente.";
       this.LlenarGrid();
}
catch (Exception ex)
{
this.lblError.Text = string.Format("Ocurrió un error al eliminar el cliete: {0}", ex.Message);
}



Para terminar con nuestro ejemplo, vamos a observar el código alojado en el evento click del botón guardar, en el cual se ejecutan las inserciones y actualizaciones a nuestra DB:

try
{
var serv = new NorthwindService.NorthwindEntities(newUri("http://localhost:1995/NorttwindAccess.svc"));

       if (this.hfAccion.Value.Equals("Nuevo"))
       {
NorthwindService.Customers customer = new NorthwindService.Customers
             {
                    CustomerID = this.txtID.Text,
                    ContactName = this.txtNombre.Text,
                    CompanyName = this.txtCompania.Text
             };
             serv.AddToCustomers(customer);
       }
       else
       {
                               NorthwindService.Customers modificarCustomer =

(from c in serv.Customers
              where c.CustomerID.Equals(this.txtID.Text)
              select c).Single();
              modificarCustomer.ContactName = this.txtNombre.Text;
              modificarCustomer.CompanyName = this.txtCompania.Text;
              serv.UpdateObject(modificarCustomer);
       }

       serv.SaveChanges();
       this.lblError.Text = "El cliente se actualizó correctamente.";
       this.hfAccion.Value = "Nuevo";
       this.txtID.Enabled = true;
       this.LlenarGrid();
}
catch (Exception ex)
{
this.lblError.Text = string.Format("Ocurrió un error al ingresar el cliete: {0}", ex.Message);
}

Con esto doy por terminado el artículo, espero que sea de gran utilidad para muchos, adicional el link de los fuentes de la solución y el .bak de la base de datos a continuación. En un próximo artículo estaré mostrando como consumir estos Data Services  mediante Jquery a través de una petición AJAX.

Saludos,
Edner LLacsa
http://ednerllacsa.blogspot.com/

miércoles, 27 de noviembre de 2013

Como desarrollar un servicio WEB con WCF

Dentro de una arquitectura orienta a servicios (SOA), es muy probable que nos veamos enfrentados a realizar servicios WEB, como hacerlo con las nuevas tecnologías? A continuación ilustro como desarrollar un servicio WEB con WCF en 7 pasos:

  • Creando un WCF Service Library
  • Configurando el contrato
  • Implementando el contrato del servicio
  • Creando un WCF Service Application
  • Configurando los EndPoitns
  • Probando el servicio
  • Consumiendo un servicio desde un cliente
Problema: El servicio que se desarrollara a continuación, simulará la revisión sobre una la lista negra/clienton, este revisará el último dígito del número de identificación proporcionado, si es par retornará VERDADERO (o sea es NEGATIVO), caso contrario si es impar retornará FALSO.
1. Creando un WCF Service Library
  • Crear un nuevo proyecto de tipo WCF(para este ejemplo en lenguaje C#), luego seleccionamos la plantilla WCF Service Library y lo nombramos así: ListaClintonService


  • Abrimos las propiedades del proyecto ListaClintonService y cambios el namespace o espacio de nombres que viene por defecto por: com.micompania.ListaClintonService
2. Configurando el contrato

  • Renombramos el archivo IService1.cs por ListaClintonServiceContract.cs y dentro del código de este cambiamos el namespace por: com.micompania.ListaClintonService y renombramos el nombre de la interfaz.
  • Luego borramos de ListaClintonServiceContract.cs
- Todos los comentarios
- La definición de la clase CompositeType
- Y los métodos GetData y GetDataUsingDataContract que se encuentran en la Interface
  • Modificamos el atributo [ServiceContract] de la clase ListaClintonServiceContract.cs e incluimos http://micompania.com/services/ListaClintonService
  • En la definición de la clase ListaClintonServiceContract definimos el método verificarDocumento que recibe como parámetro un string (numeroDocumento) y retorna un bool (Resultado).
  • Adicionamos al método verificarDocumento el atributo [OperationContract]

3. Implementando el contrato del servicio
  • Renombramos el archivo Service1.cs por ListaClintonServiceContractImplementation.cs y dentro del código de este cambiamos el namespace por: com.micompania.ListaClintonService y renombramos el nombre de la clase.
  • Borramos de la clase ListaClintonServiceContractImplementation.cs
-Todos los comentarios
-Y los métodos GetData y GetDataUsingDataContract
  • Implementamos la clase ListaClintonServiceContract


  • Definimos el Método:


Hacemos el build del proyecto: ListaClintonService 4. Creando un WCF Service Application
  • Adicionamos un nuevo proyecto de tipo Web y seleccionamos la plantilla WCF Service Application y lo nombramos así: ListaClintonServiceIISHost

  • En la propiedades del proyecto ListaClintonServiceIISHost en el tab WEB de la sección Servers especificamos el puerto: 8081 y guardamos los cambios.

  • Borramos del proyecto ListaClintonServiceIISHost
-El archivo IService1.cs
-El archivo Service1.svc
-El directorio App_Data
  • Adicionamos una referencia a ListaClintonService
  • Renombramos el archivo Service1.svc a ListaClintonService.svc
  • Dento del código del archivo ListaClintonService.svc cambiamos el atributo service a: com.micompania.ListaClintonService.ListaClintonServiceContractImplementation y borramos el atributo CodeBehind junto con su contenido.


  • Guardamos y construimos el proyecto ListaClintonServiceIISHost
5. Configurar los endPoitns del proyecto ListaClintonServiceIISHost
  • Hacemos clic derecho sobre el archivo de configuración, y hacemos clic en Edit WCF Configuraton
  • Renombramos los comportamientos, nombre del servicio y el contrato así:


  • Guardar los cambios y cerrar:

6. Probar el servicio ListaClintonService
  • Clic derecho sobre el servicio ListaClintonService.svc y colocar set as start page
  • Clic derecho sobre el servicio ListaClintonService.svc debug, start new instance
  • Se ha desplegado en nuestro IIS nuestro primer webService sobre WCF


7. Consumir un servicio:
  • Crear un proyecto WINDOWS con el Nombre ClientListaClintonService y adicione referencia de Servicio:

  • Haga clic en Discover para buscar los servicios locales, coloque en el NameSpace ClintonService


  • Adicione el NameSpace: ClientListaClintonService.ClintonService;
  • En la interfaz grafica coloque los siguientes controles:txtNumeroDoc ylblResultadoDescripcion donde mostrara el resultado

  • Proceda Añadir el siguiente codigo en el boton:
private void Aceptar_Click(object sender, EventArgs e) { ClintonService.ListaClintonServiceContractClient newLista = new ListaClintonServiceContractClient();
if (newLista.verificarDocumento(this.txtNumeroDoc.Text)) this.lblResultadoDescripcion.Text = "Esta en lista Negra";
else this.lblResultadoDescripcion.Text = "No esta en lista Negra";
}
  • Resultado con numero documento par:

  • Resultado con numero documento Impar:







Edner Llacsa.