C#CódigoVisual Studio

Desarrollando un Servicio SOAP sobre WCF

Hola a todos!

En la siguiente entrada estaremos viendo paso a paso como desarrollar un servicio SOAP sobre WCF.

Donde tendremos como objetivo:

  • Realizar el CRUD de la entidad Usuario.cs
  • Implementar pruebas unitarias del servicio UsuariosServices.svc

Habiendo definido nuestros objetivos, comencemos.

Para este ejemplo, usaremos: SQL Server 2017 y Visual Studio 2017 Community (bajo C#).

En primer lugar, crearemos un proyecto del tipo Aplicación  de servicios WCF, el cual encontraremos en WCF. Lo llamaremos PeruNETDevelopment.Services. (Figura 1)

Figura 1.

Luego de crear nuestro proyecto, observaremos la siguiente estructura en la ventana del explorador de soluciones. (Figura 2)

Figura 2.

Procedemos a eliminar IService1.cs y Service1.svc (interfaz y servicio respectivamente) generados por default en el proyecto.

A continuación, adicionaremos un nuevo elemento del tipo Servicio WCF, al cual llamaremos UsuariosServices.svc. (Figura 3).

Figura 3.

Seguidamente, adicionaremos las siguientes carpetas dentro del proyecto: Dominio, Errores y Persistencia. Así mismo, dentro de cada una agregaremos clases c#, con los nombres Usuario.cs, UsuarioException.cs UsuarioDAO.cs, respectivamente.

Ahora, nuestra estructura del proyecto es la siguiente. (Figura 4)

Figura 4.

Editaremos el archivo Usuario.cs, donde usaremos la anotación DataContract y para cada atributo DataMember:

  • El atributo sEstado no es requerido, eso lo especificamos con [DataMember(IsRequired=false)]
using System.Runtime.Serialization;

namespace PeruNETDevelopment.Services.Dominio
{
    [DataContract]
    public class Usuario
    {
        [DataMember]
        public int cUsuario { get; set; }
        [DataMember]
        public string sUsuario { get; set; }
        [DataMember]
        public string dContraseña { get; set; }
        [DataMember]
        public int nDocumento { get; set; }
        [DataMember(IsRequired = false)]
        public string sEstado { get; set; }
    }
}

Editaremos el archivo UsuarioException.cs, donde usaremos la anotación DataContract y para cada atributo DataMember:

using System.Runtime.Serialization;

namespace PeruNETDevelopment.Services.Errores
{
    [DataContract]
    public class UsuarioException
    {
        [DataMember]
        public string Codigo { get; set; }
        [DataMember]
        public string Descripcion { get; set; }
    }
}

Editaremos el archivo UsuarioDAO.cs, agregando lo siguiente:

private string CadenaConexion = "Data Source=(local);Initial Catalog=DBUsuarios;User ID=usrqas;Password=***;";
  • Crear:
public Usuario Crear(Usuario usuarioACrear)
{
    Usuario usuarioCreado = null;
    string sql = "Insert into usuario values(@susuario, @dcontraseña, @ndocumento, @sestado)";
    
    using (SqlConnection conexion = new SqlConnection(CadenaConexion))
    {
        conexion.Open();
        using (SqlCommand comando = new SqlCommand(sql, conexion))
        {
            comando.Parameters.Add(new SqlParameter("@susuario", usuarioACrear.sUsuario));
            comando.Parameters.Add(new SqlParameter("@dcontraseña", usuarioACrear.dContraseña));
            comando.Parameters.Add(new SqlParameter("@ndocumento", usuarioACrear.nDocumento));
            comando.Parameters.Add(new SqlParameter("@sestado", usuarioACrear.sEstado));
            comando.ExecuteNonQuery();
        }
    }
    usuarioCreado = Obtener(usuarioACrear.nDocumento);
    return usuarioCreado;
}
  • Obtener:
public Usuario Obtener(int nDocumento)
        {
            Usuario usuarioEncontrado = null;
            string sql = "SELECT * FROM Usuario WHERE nDocumento = @ndocumento";
            using (SqlConnection conexion = new SqlConnection(CadenaConexion))
            {
                conexion.Open();
                using (SqlCommand comando = new SqlCommand(sql, conexion))
                {
                    comando.Parameters.Add(new SqlParameter("@ndocumento", nDocumento));
                    using (SqlDataReader resultado = comando.ExecuteReader())
                    {
                        if (resultado.Read())
                        {
                            usuarioEncontrado = new Usuario
                            {
                                cUsuario = (int)resultado["cUsuario"],
                                sUsuario = (string)resultado["sUsuario"],
                                dContraseña = (string)resultado["dContraseña"],
                                nDocumento = (int)resultado["nDocumento"],
                                sEstado = (string)resultado["sEstado"]
                            };
                        }
                    }
                }
            }
            return usuarioEncontrado;
        }
  • Modificar:
public Usuario Modificar(Usuario usuarioAModificar)
{
    Usuario usuarioModificado = null;
    var sql = "update usuario set sUsuario = @susuario, dcontraseña = @dcontraseña where ndocumento = @ndocumento";
    using (SqlConnection conexion = new SqlConnection(CadenaConexion))
    {
        conexion.Open();
        using (SqlCommand comando = new SqlCommand(sql, conexion))
        {
            comando.Parameters.Add(new SqlParameter("@susuario", usuarioAModificar.sUsuario));
            comando.Parameters.Add(new SqlParameter("@dcontraseña", usuarioAModificar.dContraseña));
            comando.Parameters.Add(new SqlParameter("@ndocumento", usuarioAModificar.nDocumento));
            comando.ExecuteNonQuery();
        }
    }
    usuarioModificado = Obtener(usuarioAModificar.nDocumento);
    return usuarioModificado;
}
  • Eliminar:
public void Eliminar(int dni)
{
    var sql = "DELETE FROM usuario WHERE ndocumento = @ndocumento";
    using (SqlConnection conexion = new SqlConnection(CadenaConexion))
    {
        conexion.Open();
        using (SqlCommand comando = new SqlCommand(sql, conexion))
        {
            comando.Parameters.Add(new SqlParameter("@ndocumento", dni));
            comando.ExecuteNonQuery();
        }
    }
}
  • Listar:
public List<Usuario> Listar()
{
    List<Usuario> usuariosEncontrados = new List<Usuario>();
    Usuario usuarioEncontrado = null;
    var sql = "SELECT * FROM usuario";
    using (SqlConnection conexion = new SqlConnection(CadenaConexion))
    {
        conexion.Open();
        using (SqlCommand comando = new SqlCommand(sql, conexion))
        {
            using (SqlDataReader resultado = comando.ExecuteReader())
            {
                while (resultado.Read())
                {
                    usuarioEncontrado = new Usuario()
                    {
                        cUsuario = (int)resultado["cUsuario"],
                        sUsuario = (string)resultado["sUsuario"],
                        dContraseña = (string)resultado["dContraseña"],
                        sEstado = (string)resultado["sEstado"]
                    };

                    usuariosEncontrados.Add(usuarioEncontrado);
                }
            }
        }
        return usuariosEncontrados;
    }
}

Editaremos el archivo IUsuariosServices.cs:

using System.Collections.Generic;
using System.ServiceModel;
using WCFServices.Dominio;
using WCFServices.Errores;

namespace WCFServices
{
    // NOTA: puede usar el comando "Rename" del menú "Refactorizar" para cambiar el nombre de interfaz "IUsuariosServices" en el código y en el archivo de configuración a la vez.
    [ServiceContract]
    public interface IUsuariosServices
    {
        [FaultContract(typeof(UsuarioException))]
        [OperationContract]
        Usuario CrearUsuario(Usuario usuarioACrear);

        [OperationContract]
        Usuario ObtenerUsuario(int dni);

        [OperationContract]
        Usuario ModificarUsuario(Usuario usuarioAModificar);

        [OperationContract]
        void EliminarUsuario(int dni);

        [OperationContract]
        List<Usuario> ListaUsuarios();
    }
}

Editaremos UsuariosServices.svc:

using PeruNETDevelopment.Services.Dominio;
using PeruNETDevelopment.Services.Errores;
using PeruNETDevelopment.Services.Persistencia;
using System.Collections.Generic;
using System.ServiceModel;

namespace PeruNETDevelopment.Services
{
    public class UsuariosServices : IUsuariosServices
    {
        private UsuarioDAO usuarioDAO = new UsuarioDAO();

        public Usuario CrearUsuario(Usuario usuarioACrear)
        {
            if (usuarioDAO.Obtener(usuarioACrear.nDocumento) != null)
            {
                throw new FaultException<UsuarioException>(
                    new UsuarioException()
                    {
                        Codigo = "101",
                        Descripcion = "El usuario ya existe"
                    },
                    new FaultReason("Error al intentar crear usuario")
                );
            }

            return usuarioDAO.Crear(usuarioACrear);
        }

        public Usuario ObtenerUsuario(int nDocumento)
        {
            if (usuarioDAO.Obtener(nDocumento) == null)
            {
                throw new FaultException<UsuarioException>(
                     new UsuarioException()
                     {
                         Codigo = "102",
                         Descripcion = "El usuario no existe"
                     },
                     new FaultReason("Error al intentar obtener usuario")
                );
            }
            return usuarioDAO.Obtener(nDocumento);
        }

        public Usuario ModificarUsuario(Usuario usuarioAModificar)
        {
            if (usuarioAModificar.sEstado == "I")
            {
                throw new FaultException<UsuarioException>(
                    new UsuarioException()
                    {
                        Codigo = "103",
                        Descripcion = "No se puede modificar usuario con estado Inactivo"
                    }, new FaultReason("Error al intentar modificar usuario")
               );
            }
            return usuarioDAO.Modificar(usuarioAModificar);
        }

        public void EliminarUsuario(int dni) { usuarioDAO.Eliminar(dni); }

        public List<Usuario> ListaUsuarios() { return usuarioDAO.Listar(); }
    }
}

Muy bien, hasta este punto tenemos:

  • CRUD de la entidad Alumno (ejemplo básico)
  • Implementación del servicio, con algunas excepciones tales como:
    • CrearUsuario: Valida si el usuario ya existe
    • ModificarUsuario: Valida estado del usuario para ser modificado

Ahora, a modo de comprobar veamos el servicio en el explorador, UsuariosServices WSDL. (Figura 5)

(Figura 5)

Para probar el servicio se ejecutará el proyecto, haciendo F5 sobre el servicio UsuarioServices. (Figura 6).

  • Paso 1: Doble clic sobre el método ListaUsuarios().
  • Paso 2: Doble clic sobre invocar.
  • Paso 3: Clic para ver detalle de listado retornado.

(Figura 6)

Esto es todo por ahora!

Continuaremos con la implementación de las pruebas unitarias en una siguiente entrada.

Para encontrar el proyecto pueden dar clic aquí.

Deja un comentario

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