Programación en Capas

 

Ejemplo en C# Ejemplo en PHP Visual Studio Ej. en ASP y C# Volver

Ejemplo ASP.NET y C#

 

Partiendo de lo aprendido en mi post anterior realizaremos una aplicación en este caso haremos un foro basico en el cual se podran utilizar las funciones  consultar, insertar y borrar un registro en tres capas.  Es importante haber leido el post sobre tres capas antes mencionado, puesto que no se detallara aqui.

 

En este post aprenderemos mucho mas que solo las 3 capas, aprenderemos a crear el esquema de nuestra pagina, la pagina principal (Master Page), algo de CSS, algo mas de JavaScript, y por supuesto como hacer tus propias imagenes y usarlas en tu HTML de manera facil.

 

Bueno empecemos por que es demaciado lo que hay que cubrir.

 

Base de datos

 

Para iniciar nuestra aplicación necesitaremos crear la base de datos con la sentencia:


create database DBForo

 

A continuacion necesitaremos acceder a esta base de datos con la siguente sentencia:


use DBForo

 

El siguiente paso es crear las tablas que necesitaremos, bueno en este paso es indispensable que se tenga un conocimiento basico de la estructura de las bases de datos si tienes dudas visita este sitio Aqui

 

Ahora procedemos a crear las tablas de nuestra base de datos, crearemos 3 tablas, La tabla usuarios que nos guardara la información de los usuarios, la tabla posts que almacenara los post que haya realizado un usuario, y por ultimo la tabla comentarios que almacenara los comentarios de cada post, realizados por cada usuario.

 

create table Usuarios(

usuario varchar(20) primary key,

password varchar (20) not null,

nombre varchar(50) not null,

apellido varchar(50) not null,

pais int not null,

sexo char(1),

correo varchar(50),

telefono varchar(30)

)

GO

 

create table Posts(

idpost int identity primary key,

nombre varchar(50),

descripcion varchar (5000),

usuario varchar(20) references Usuarios(usuario)

)

GO

 

create table Comentarios(

idcomentario int identity,

usuario varchar(20) references Usuarios(usuario),

idpost int references Posts(idpost) on delete cascade,

comentario varchar(5000) not null,

hora datetime not null

)

 

Con esto ya tenemos listos todos los campos que necesitaremos, es hora de crear los procedimientos almacenados que se van a utilizar, para saber el numero exacto y tipos de procedimientos que se necesitan crear, primero debemos hacer un analisis de las operaciones que se intentan realizar en la aplicacion, bueno para este Foro solo utilizaremos 5 procedimientos almacenados los cuales se presentan a continuacion:

 

create proc insusuario(

@usuario varchar(20) ,

@password varchar (20) ,

@nombre varchar(50) ,

@apellido varchar(50) ,

@pais int,

@sexo char(1),

@correo varchar(50),

@telefono varchar(30)

)

as insert into usuarios values(@usuario,@password,@nombre,@apellido,@pais,@sexo,@correo,@telefono)

GO

 

create proc insComentario(

@usuario varchar(20),

@idpost int,

@comentario varchar(5000)

)

as insert into comentarios values(@usuario,@idpost,@comentario,GETDATE())

GO

 

create proc delPost(

@idpost int

)

as delete from posts where idpost=@idpost

GO

 

create proc insPost(

@nombre varchar(50),

@descripcion varchar(5000),

@usuario varchar(20)

)

as insert into Posts values (@nombre, @descripcion,@usuario)

GO

 

create proc updPost(

@nombre varchar(50),

@descripcion varchar(5000),

@idpost int

)

as update posts set nombre = @nombre, descripcion = @descripcion where idpost = @idpost

GO

insusuario: Servira para insertar un usuario a las base de datos.
insComentario: Insertara un comentario realizado por un usuario en un post determinado.
delPost: Borrara un post determinado.
insPost: Insertara un post a un usuario determinado.
updPost: Modificara un post determinado.

 

Parecería un poco redundante el nombre con la descripción, esto ayuda muchísimo a la hora de utilizar los procedimientos, por que no tienes que regresar a ver como se llaman, además si no se tiene cuidado, podrías repetir nombres y tener que volver a crear o en su defecto renombrar tus procedimientos almacenados.

 

Ok ya tenemos base de datos, tablas, procedimientos, ahora solo nos queda insertar algunos datos de prueba para que quede todo listo para empezar a programar nuestro foro.

 

insert into usuarios values ('pedro','demo','Pedro','Rodriguez',21,'M','pedrorodriguez@gmail.com','3827982173')

insert into usuarios values ('ana','demo','Ana','Huemil',1,'F','ana_huemil@hotmail.com','384872828')

insert into usuarios values ('juan','demo','Juan','Vazquez',9,'M','juan.vazquez.yahoo.com','323413214')

insert into Posts values ('Funcionamiento basico del Foro','Descripcion de Funciones del Foro','juan')

insert into Posts values ('Programando en ASP','Programa basico de asp','pedro')

insert into Posts values ('Crear un foro basico','Hola gente!!! Estoy haciendo un site y en una parte necesito hacer un foro, no tiene que ser nada increible ni nada muy grande, solamente poder postear mensajes y autor del mensaje...

 

El tema es que en este momento me estaba por poner a programarlo y me surgieron varias dudas en cuanto a el funcionamiento, osea donde guardo los mensajes principalmente... Yo tenia penasdo hacer alguna cosa con archivos indexados en una base de datos (mysql) para no cargarla mucho....

 

Pero antes de ponerme a hacer esto me puse a buscar en internet y encontre que en varios lados "enseñan" a crear un foro guardando toda la informacion en la base de datos y armando los "threds" haciendo consultas que filtren todo lo que no es del tema especificado... en estos lugares que comento guardan el texto, osea el cuerpo del mensaje en la base de datos, esto no la enlenteceria???? yo tenia "entendido" que habia que tratar de guardar la menor cantidad de informacion posible en las bases para tarden los menos posible en los manejos que hacen...

 

pero es solo una idea mia, no se si sera verdad o no...

Alguien sabe como funcionan los foros posta??? o que me recomiendan hacer???

Este ultimo metodo de guardar todo en la base de datos es extremadamente facil,

porque armas los temas con consultas y no te tenes que preocupar de nada...

Pero tengo ganas de hacer algo lo mas "aproximado" a la realidad posible... no algo facilongo para salir del paso....

Bueno, espero sus propuestas

saludos!!!!!!!','pedro')

 

insert into Comentarios values ('ana',3,'Hacete un favor y usa algo ya hecho. Con las dudas que tenes, la magnitud del proyecto te supera ampliamente.',GETDATE())

insert into Comentarios values ('juan',3,'Puede que haya algún otro paquete que sea todavía más simple si no estás buscando tantos features..',GETDATE())

insert into Comentarios values ('pedro',3,'gracias a todos, pero la verdad es que tengo ganas de hacerlo yo,  porque es algo MUY simple... osea ni siquiera quiero hacer subforos, osea es un lugar donde se agregan temas y se puede comentar esos temas, no es que entro y tengo 40 subforos... asi que voy a seguir haciendolo por mi cuenta que de paso aprendo... muchas gracias a todos... saludos!',GETDATE())

insert into Comentarios values ('ana',1,'Como se crea un post??',GETDATE())

insert into Comentarios values ('juan',1,'Solo vaz a mis posts y seleccionas crear un post, le das un titulo y una descripcion y por ultimo crear post',GETDATE())

insert into Comentarios values ('ana',1,'Gracias otra pregunta, como se borra un comentario??',GETDATE())

 

Listo, con esto terminamos con nuestra base de datos, y continuamos con la Capa de Datos.

 

Capa de Datos

 

Antes de empezar con la capa de datos es necesario saber la estructura de la cadena de conexion, la cual se utilizara en este apartado, En caso de no tener experiencia con la cadena de conexion a SQL Server, sera necesario leer mi post anterior, este contiene los pasos detallados para crear la cadena de conexion.

 

Con la base de datos lista, empezaremos a crear nuestra primera capa, abrimos Visual Studio y crearemos un nuevo proyecto en apartado tipo de proyecto seleccionamos Visual C# y despues seleccionamos Windows, dentro de plantillas seleccionamos Plantillas instaladas de Visual Studio despues Biblioteca de Clases, llamaremos a nuestro proyecto Datos y la solucion llamada Foro, en la siguiente imagen se aclara los pasos antes descritos para la configuracion de nuestra solucion.

 

 

En el explorador de soluciones encontraremos una clase llamada class1.cs que Visual Studio por default nos crea, la eliminaremos y crearemos una nueva llamada configuracion.cs, para eliminar class1.cs daremos click derecho sobre ella y seleccionamos eliminar, confirmamos en la ventana emergente y con esto la habremos eliminado

 

 

Ahora crearemos la clase configuracion, para esto nos situamos sobre el proyecto Datos y damos click derecho, nos situamos sobre agregar y en las opciones que nos ofrece agregar, seleccionamos Clase.

 

Lo anterior nos llevara a la ventana de Agregar nuevo elemento – Datos, Aqui seleccionaremos en Plantillas > Clase y despues le pondremos el nombre de Configuracion a nuestra nueva clase.

Al crear la clase Configuracion.cs, Visual Studio nos muestra la estructura basica una clase, esta clase se necesitara hacer publica para ello le agregamos la palabra reservada public antes de class, acontinuacion utilizaremos la cadena de conexion antes mencionada.

Crearemos una variable estatica llamada cadenaConexion y le asignaremos nuestra cadena de conexion y con esto ya establecido le crearemos un metodo a la clase Configuracion el cual se llamara CadenaConexion, y se encargara de proporcionar la cadena de conexion a cualquier proceso que la necesite.

El siguiente codigo siguiente muestra como deberia de quedar nuestra clase.

namespace Datos

{

    public class Configuracion

    {

        static string cadenaConexion =

        @"Data Source=??????;Initial Catalog=DBForo;User ID=sa;Password=?????";

        public static string CadenaConexion

        {

            get { return cadenaConexion; }

        }

    }

}

 

Se muestra a continuacion la imagen del Visual Studio el cual servira como referencia para la creacion de este proyecto.

De la misma manera que agregamos la clase de Configuracion, esta vez crearemos otra clase llamada MetodosDatos, esta clase contendra las rutinas para acceder a la base de datos.

Al igual que en la clase Configuracion.cs, a MetodosDatos.cs le agregaremos la propiedad de public, pero ademas a esta clase le agregaremos dos referencias o bibliotecas estas se insertan antes del namespace y nos sirver para utilizar metodos ya establecidos en C#.

1

2

using System.Data.SqlClient;

using System.Data;

Acontinuacion agregaremos 4 metodos, “rutinas para el acceso a la base de datos”

CrearComando

Este metodo nos servira para crear un comando sql estandard como un select el cual sera regresado por su metodo return

1

2

3

4

5

6

7

8

9

10

public static SqlCommand CrearComando()

        {

            string _cadenaConexion = Configuracion.CadenaConexion;

            SqlConnection _conexion = new SqlConnection();

            _conexion.ConnectionString = _cadenaConexion;

            SqlCommand _comando = new SqlCommand();

            _comando = _conexion.CreateCommand();

            _comando.CommandType = CommandType.Text;

            return _comando;

        }

CrearComandoProc

Este metodo al igual que el anterior nos crea un comando sql, pero con la diferencia que este metodo nos creara nuestro comando de manera que pueda ejecutar nuestros procedimientos almacenados que ya se encuentran establecidos en nuestra base de datos.

Es importante señalar que este metodo acepta un parametro llamado proc el cual es el nombre de el procedimiento almacenado que se quiera utilizar, de esta manera podemos preparar un comando para un procedimiento almacenado especifico y despues utilizarlo.

1

2

3

4

5

6

7

8

public static SqlCommand CrearComandoProc(string proc)

{

    string _cadenaConexion = Configuracion.CadenaConexion;

    SqlConnection _conexion = new SqlConnection(_cadenaConexion);

    SqlCommand _comando = new SqlCommand(proc, _conexion);

    _comando.CommandType = CommandType.StoredProcedure;

    return _comando;

}

EjecutarComando

Este metodo obtiene como parametro un comando sql que proviene de el metodo anterior CrearComandoProc, este metodo ejecuta el procedimineto almacenado que se le ha asignado al comando. Este sera el metodo en donde se llevaran a cabo el agregar, eliminar y actualizar, todo dependiendo de los procedimientos almacenados antes definidos en la base de datos.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public static int EjecutarComando(SqlCommand comando)

{

    try

    {

        comando.Connection.Open();

        return comando.ExecuteNonQuery();

    }

    catch { throw; }

    finally

    {

        comando.Connection.Dispose();

        comando.Connection.Close();

    }

}

EjecutarComandoSelect

Este metodo ejecutara un comando select el cual nos regresara un datatable con todos los registros que se encuentren en alguna tabla dada, toma como parametro el comando que contiene la sentencia sql select.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

public static DataTable EjecutarComandoSelect(SqlCommand comando)

{

    DataTable _tabla = new DataTable();

    try

    {

        comando.Connection.Open();

        SqlDataAdapter adaptador = new SqlDataAdapter();

        adaptador.SelectCommand = comando;

        adaptador.Fill(_tabla);

    }

    catch (Exception ex)

    { throw ex; }

    finally

    { comando.Connection.Close(); }

    return _tabla;

}

Estas serian todas las clases que MetodosDatos.cs contendra, para evitar confusiones he agregado una imagen que muestra la estructura completa de nuestro metodo.

Con los metodos generales definidos ahora continuaremos creando los metodos de acceso para cada una de las funciones que necesitaremos para el foro.

Crearemos una nueva clase en la capa de datos que se llamará AccesoDatos y tendra la funcion de autentificar y registrar a los usuarios, no olvidarse de agregar las bibliotecas System.Data y System.Data.SqlClient asi como la propiedad public.

Los metodos para “AccesoDatos” se muestran a continuacion:

insertarUsuario
Tendra la funcion de insertar un usuario por medio de el porcedimiento almacenado insUsuario, el codigo se muestra a continuancion.

public static int insertarUsuario(string usuario, string password, string nombre, string apellido,int pais, char sexo, string correo, string telefono)

       {

           SqlCommand _comando = MetodosDatos.CrearComandoProc("insUsuario");

           _comando.Parameters.AddWithValue("@usuario", usuario);

           _comando.Parameters.AddWithValue("@password", password);

           _comando.Parameters.AddWithValue("@nombre", nombre);

           _comando.Parameters.AddWithValue("@apellido", apellido);

           _comando.Parameters.AddWithValue("@pais", pais);

           _comando.Parameters.AddWithValue("@sexo", sexo);

           _comando.Parameters.AddWithValue("@correo", correo);

           _comando.Parameters.AddWithValue("@telefono", telefono);

           return MetodosDatos.EjecutarComando(_comando);

       }

 

verificarUsuario
Este metodo tiene la funcion de verificar si el usuario y el password ingresados por el usuario coniciden en la base de datos, esto es, se compara si existe un usuario que tenga como usuario y como password los que se han pasado como parametros, el codigo se muestra a continuacion.

public static DataTable verificarUsuario(string usuario, string pass)

        {

            SqlCommand _comando = MetodosDatos.CrearComando();

            _comando.CommandText = "SELECT usuario FROM usuarios WHERE usuario = '"+usuario+"' AND password = '"+pass+"'";

            return MetodosDatos.EjecutarComandoSelect(_comando);

        }

 

como referencia, la siguiente imagen, muestra como se estructura la clase AccesoDatos de la capa de datos.

Ahora crearemos una carpeta que contendra los metodos ordenados por formulario, para esto, necesitamos hacer click derecho en la capa de datos seleccionar agregar y en el menu emergente nueva carpeta (ver imagen) despues le asignamos el nombre de Views.

Despues de haber creado la carpeta se creara la clase misComentariosDatos dentro de esta carpeta, para esto haremos click derecho en agregar y despues seleccionaremos clase (ver imagen). En la ventana Agregar nuevo elemento en categorias seleccionamos codigo y en plantillas clase por ultimo le asignamos el nombre de misComentariosDatos.

Ahora en la clase misComentariosDatos se creará el siguiente metodo.

obtenerComentarios
Este metodo se utiliza para obtener los comentarios por usuario, para logralo se necesita la hora del comentario, el nombre del post donde se encuentra el comentario y el comentario, teniendo esto en cuenta se necesita hacer un inner join para obtener el nombre de el post. No hay que olvidar cambiar la propiedad de la clase a publica y las referencias a las bibliotecas System.Data y System.Data.SqlClient el codigo se muestra a continuacion:

public static DataTable ObtenerComentarios(string usuario)

{

    SqlCommand _comando = MetodosDatos.CrearComando();

    _comando.CommandText = "SELECT hora, nombre, comentario FROM comentarios INNER JOIN posts ON comentarios.idpost = posts.idpost WHERE comentarios.usuario = '" + usuario + "'";

    return MetodosDatos.EjecutarComandoSelect(_comando);

}

Como referencia, la siguiente imagen, muestra como se estructura la clase misComentariosDatos de la capa de datos.

Al igual que se hizo anteriormente, se creara la clase misPostsDatos en la carpeta de Views de la capa de Datos(agregar las bibliotecas System.Data y System.Data.SqlClient ademas de la propiedad publica), esta clase se encargara de administrar los posts y contendra los siguientes metodos.

obtenerMisPosts
Obtiene todos los posts hechos por el usuario.

public static DataTable obtenerMisPosts(string usuario)

        {

            SqlCommand _comando = MetodosDatos.CrearComando();

            _comando.CommandText = "SELECT idpost,nombre,descripcion FROM posts WHERE usuario = '" + usuario + "'";

            return MetodosDatos.EjecutarComandoSelect(_comando);

        }

eliminarPost
Elimina un post basandose en su id usando el procedimiento almacenado delPost.

public static int eliminarPost(int post)

        {

            SqlCommand _comando = MetodosDatos.CrearComandoProc("delPost");

            _comando.Parameters.AddWithValue("@idpost", post);

            return MetodosDatos.EjecutarComando(_comando);

        }

insertarPost
Crea un post usando el procedimiento almacenado insPost el cual necesita de un nombre, una descripcion y el usuario que lo esta creando.

public static int insertarPost(string nombre,string descripcion,string usuario)

        {

            SqlCommand _comando = MetodosDatos.CrearComandoProc("insPost");

            _comando.Parameters.AddWithValue("@nombre", nombre);

            _comando.Parameters.AddWithValue("@descripcion", descripcion);

            _comando.Parameters.AddWithValue("@usuario", usuario);

            return MetodosDatos.EjecutarComando(_comando);

        }

ctualizarPost
Este metodo utiliza el procedimiento almacenado updPost el cual permite modificar un post basandose en su numero de id.

public static int actualizarPost(string nombre, string descripcion, int post)

        {

            SqlCommand _comando = MetodosDatos.CrearComandoProc("updPost");

            _comando.Parameters.AddWithValue("@nombre", nombre);

            _comando.Parameters.AddWithValue("@descripcion", descripcion);

            _comando.Parameters.AddWithValue("@idpost", post);

            return MetodosDatos.EjecutarComando(_comando);

        }

obtenerDatosPosts
Obtiene los datos de un post por medio de su id, esto con el fin de mostrar un encabezado al mostrar los comentarios.

public static DataTable obtenerDatosPosts(int post)

        {

            SqlCommand _comando = MetodosDatos.CrearComando();

            _comando.CommandText = "SELECT nombre,descripcion FROM posts WHERE idpost = " + post;

            return MetodosDatos.EjecutarComandoSelect(_comando);

        }

Como referencia, la siguiente imagen, muestra como se estructura la clase misPostsDatos de la capa de datos.

Ahora bien, se creara la clase miperfilDatos en la carpeta de Views de la capa de Datos(agregar las bibliotecas System.Data y System.Data.SqlClient ademas de la propiedad publica), esta clase se encargara de mostrar los datos de los usuarios y contendra el siguiente metodo.

obtenerDatos
Este metodo tiene la funcion de obtener todos los datos del usuario.

1

2

3

4

5

6

7

    public static DataTable obtenerDatos(string usuario)

    {

        SqlCommand _comando = MetodosDatos.CrearComando();

        _comando.CommandText = "SELECT * FROM Usuarios WHERE usuario ='" + usuario + "'";

        return MetodosDatos.EjecutarComandoSelect(_comando);

    }

}

Como referencia, la siguiente imagen, muestra como se estructura la clase perfilDatos de la capa de datos.

Por ultimo, se creara la clase todosPostsDatos en la carpeta de Views de la capa de Datos(agregar las bibliotecas System.Data y System.Data.SqlClient ademas de la propiedad publica), esta se encargara de realizar todas los operaciones por parte del usuario en cuanto a comentarios y posts y contendra los siguientes metodos.

obtenerTodosPosts
Obtiene todos los posts que se han creado por todos los usuarios.

public static DataTable obtenerTodosPosts()

{

    SqlCommand _comando = MetodosDatos.CrearComando();

    _comando.CommandText = "SELECT * FROM posts";

    return MetodosDatos.EjecutarComandoSelect(_comando);

}

 

obtenerInfoPost
Obtiene la informacion de un post en particular, para esto se necesita pasar como parametro el id del post.

1

2

3

4

5

6

public static DataTable obtenerInfoPost(int post)

{

    SqlCommand _comando = MetodosDatos.CrearComando();

    _comando.CommandText = "SELECT * FROM posts WHERE idpost=" + post ;

    return MetodosDatos.EjecutarComandoSelect(_comando);

}

obtenerComentarios
Este metodo ob

tiene todos los comentarios hechos en un post en particular, para ello, se necesita el id del post.

1

2

3

4

5

6

public static DataTable obtenerComentarios(int post)

{

    SqlCommand _comando = MetodosDatos.CrearComando();

    _comando.CommandText = "SELECT * FROM comentarios WHERE idpost=" + post ;

    return MetodosDatos.EjecutarComandoSelect(_comando);

}

insertarComentario
Este metodo inserta el comentario hecho en un post, para esto se utiliza el procedimiento almacenado “insComentario” y este necesita de tres parametros, el usuario que hizo el comentario, el id del post donde se colocara el comentario y por ultimo el comentario.

1

2

3

4

5

6

7

8

9

    public static int insertarComentario(string usuario, int post, string comentario)

    {

        SqlCommand _comando = MetodosDatos.CrearComandoProc("insComentario");

        _comando.Parameters.AddWithValue("@usuario", usuario);

        _comando.Parameters.AddWithValue("@idpost", post);

        _comando.Parameters.AddWithValue("@comentario", comentario);

        return MetodosDatos.EjecutarComando(_comando);

    }

}

Como referencia, la siguiente imagen, muestra como se estructura la clase todosPostsDatos de la capa de datos.

Asi terminamos con la capa de Datos, solo como referencia se muestra la imagen de como deberia quedar la estructura de la capa de Datos.

Capa de Negocio

 

 

Ahora crearemos la capa de negocio la cual se encargara de comunicar a la capa de datos con la capa de presentacion.

 

Primero crearemos el proyecto, para esto daremos click derecho en la solucion Foro y seleccionaremos Nuevo Proyecto

 

 

 

En la pantalla agregar nuevo proyecto, seleccionaremos en los tipos de proyectos, windows y en plantillas seleccionaremos bibliotecas de clases, a esta biblioteca de clases le podremos el nombre de Negocio (ver imagen).

Al igual como se realizo en la capa de datos, se borrara la clase que Visual Studio nos creo por default y la reemplazaremos por una llamada AccesoLogica. Antes de empezar a editar nuestra clase AccesoLogica, agregaremos la referencia de la capa de datos a la de Negocio, necesitamos agregar la referencia de nuestra capa anterior por lo que en referencias de el proyecto negocio le haremos un click derecho y seleccionaremos agregar referencia.
Visual Studio nos presenta con una ventana en la cual podemos elegir varios tipos de referencias, en esta ventana seleccionaremos la pestaña de Proyectos y ahi nos aparece nuestra biblioteca de clases Datos la cual esta contenida en nuestra Solucion llamada TresCapas. la seleccionamos y aceptamos. (detallado en mi 
post anterior).

Con la capa de Datos referenciada en la capa de Negocio, empezaremos a editar nuestra clase AccesoLogica.cs, primero agregaremos las bibliotecas

1

2

using Datos;

using System.Data;

Sin olvidar tambien agregar el atributo de public a nuestra clase.

En respecto a los metodos de esta clase tenemos dos los cuales se encargan de administrar a los usuarios.

insertarUsuario
Este metodo agrega a un usuario, para ello es necesario se necesitan los datos para agregar a este usuario, los cuales ya habran sido validados en la capa de presentacion.

public static bool insertarUsuario(string usuario, string password, string nombre, string apellido, int pais, char sexo, string correo, string telefono)

{

  try

  {

    if (AccesoDatos.insertarUsuario(usuario, password, nombre, apellido, pais, sexo, correo, telefono) != 0)

      return true;

    else

      return false;

  }

  catch

  {

    return false;

  }

}

 

verificarUsuario
Este metodo se encarga de revisar en la base de datos si existe el usuario con el password introducidos, de ser asi devuelve true de lo contrario false.

public static bool verificarUsuario(string usuario, string pass)

{

  try

  {

    DataTable datos = AccesoDatos.verificarUsuario(usuario, pass);

    if (datos.Rows.Count != 0)

      return true;

    else

      return false;

  }

  catch

  {

    return false;

  }

}

 

Como referencia, la siguiente imagen, muestra como se estructura la clase AccesoLogica de la capa de Negocio.

Al igual que en la capa de datos, en esta capa se creara una carpeta llamada Views que contendra los medotos divididos por formulario.

La primera clase que crearemos en esta carpeta sera misComentariosNeg y esta clase tendra un metodo, no olvidar agregar las bibliotecas

1

2

using Datos.Views;

using System.Data;

y la propiedad public.

obtenerComentarios
Este metodo obtendra todos los comentarios que el usuario haya realizado en nuestro foro.

1

2

3

4

public static DataTable obtenerComentarios(string usuario)

{

  return misComentariosDatos.obtenerComentarios(usuario);

}

Como referencia, la siguiente imagen, muestra como se estructura la clase msComentariosNeg de la capa de Negocio.

La siguiente clase que se creara en la carpeta Views sera misPostsNeg, esta clase contendra 5 metodos, no olvidar agregar las referencias a las bibliotecas

1

2

using Datos.Views;

using System.Data;

y la propiedad public.

obtenerMisPosts
Este metodo obtiene todos los post que el usuario haya creado.

1

2

3

4

public static DataTable obtenerMisPosts(string usuario)

{

  return misPostsDatos.obtenerMisPosts(usuario);

}

obtenerDatosPosts
Este metodo obtendra todos los datos de un post en especifico basandose en el parametro post que sera el id del post seleccionado.

1

2

3

4

public static DataTable obtenerDatosPosts(int post)

{

  return misPostsDatos.obtenerDatosPosts(post);

}

eliminarPost
Este metodo eliminara un post seleccionando basandose en el id de este post.

public static bool eliminarPost(int post)

{

  try

  {

    if (misPostsDatos.eliminarPost(post) != 0)

      return true;

    else

      return false;

  }

  catch

  {

    return false;

  }

}

 

insertarPost
Este metodo creara un post y para que este se cree se pasaran como parametros el nombre del post, su descripcion y el id del usuario que lo esta creando.

public static bool insertarPost(string nombre, string descripcion, string usuario)

{

  try

  {

    if (misPostsDatos.insertarPost(nombre, descripcion, usuario) != 0)

      return true;

    else

      return false;

  }

  catch

  {

    return false;

  }

}

 

actualizarPost
Este metodo modificara los datos contenidos de un post en especifico basandose en el id de el post.

public static bool actualizarPost(string nombre, string descripcion, int post)

{

  try

  {

    if (misPostsDatos.actualizarPost(nombre, descripcion, post) != 0)

      return true;

    else

      return false;

  }

  catch

  {

    return false;

  }

}

 

Como referencia, la siguiente imagen, muestra como se estructura la clase misPostNeg de la capa de Negocio.

La siguiente clase que se creara en la carpeta Views sera perfilNeg
no olvidar agregar las bibliotecas

1

2

using Datos.Views;

using System.Data;

y la propiedad public.

obtenerDatos
Este metodo obtiene los datos de el usuario.

public static DataTable obtenerDatos(string usuario)

{

  return perfilDatos.obtenerDatos(usuario);

}

 

Como referencia, la siguiente imagen, muestra como se estructura la clase perfilNeg de la capa de Negocio.

La siguiente clase que se creara en la carpeta Views sera todosPostsNeg no olvidar agregar las bibliotecas

1

2

using Datos.Views;

using System.Data;

y la propiedad public

obtenerTodosPosts
Este metodo obtiene todos los post creados.

public static DataTable obtenerTodosPosts()

{

  return todosPostsDatos.obtenerTodosPosts();

}

 

obtenerInfoPost
Este metodo obtiene toda la informacion de un post en especifico.

public static DataTable obtenerInfoPost(int post)

{

  return todosPostsDatos.obtenerInfoPost(post);

}

 

obtenerComentarios
Este metodo obtiene todos los comentarios hechos en un post especifico.

public static DataTable obtenerComentarios(int post)

{

  return todosPostsDatos.obtenerComentarios(post);

}

 

insertarComentario
Este metodo inserta el comentario hecho por el usuario a un post en especifico para ello es necesario el id del usuario, el id del post y por ultimo el comentario hecho.

public static bool insertarComentario(string usuario, int post, string comentario)

{

  try

  {

    if (todosPostsDatos.insertarComentario(usuario, post, comentario) != 0)

      return true;

    else

      return false;

  }

  catch

  {

    return false;

  }

}

 

depurarComentario
 

Este es un metodo extra y nos sirve para depurar el comentario antes de insertarlo en la base de datos esto con el objetivo de evitar que usuarios quieran ingresar codigo html a nuestro foro y cambiar el comportamiento de nuestro foro.

 

public static string depurarComentario(string str)

{

  string temp = str.Replace("<", "");   temp = temp.Replace(">", "");

  temp = temp.Replace("&", "");

  return temp;

}

 

Como referencia, la siguiente imagen, muestra como se estructura la clase todosPostsNeg de la capa de Negocio.

 

 

Ensegida se muestra la estructura de la capa de Negocio.

Con esto terminamos nuestra capa de Negocio y ahora continuaremos con la capa de Presentacion.

Capa de Presentación

Antes de comenzar a programar nuestra capa de presentacion debemos preparar el camino, iniciaremos con las imagenes que utilizaremos para el diseño de nuestra aplicacion.

Primero veamos como va a quedar el diseño de nuestra pantalla para el login.

 

 

Para lograr esto necesitamos varias imagenes, primero el fondo (para descargarlas haz click sobre ellas y cuando seas redireccionado a la imagen haz click derecho y guardar imagen como..):

ablue
ablue.jpg

Despues el encabezado:

header
header.png

Por ultimo los botones, los cuales se dividen en dos el boton normal y el boton de hover que es cuando el puntero del mouse esta encima del boton:

btnentrar                    btnentrarhover

btnentrar.png                  btnentrarhover.png

btnregistrar                      btnregistrarhover

btnregistrar.png           btnregistrarhover.png

Es importante mantener los nombres de las imagenes, o de lo contrario deberas recordar modificar el codigo que mas adelante se presentara.

Ahora para el diseño de la pantalla para realizar el registro de un usuario es la siguiente:

Para esta pantalla ya tenemos de la pantalla anterior el fondo y el encabezado solo necesitaremos los botones correspondientes.

btnusercancelar                       btnusercancelarhover

btnusercancelar.png          btnusercancelarhover.png


btnuserregistrar                      btnuserregistrarhover

btnuserregistrar.png             btnuserregistrarhover.png

Por ultimo el diseño de la pagina principal, que va a ser la cual sera reutilizada para todas las funciones del foro.

Iniciamos con el fondo:

bluedrops
bluedrops.jpg

A continuacion el encabezado.

headerdrops
headerdrops.png

Para esta pantalla necesitaremos un fondo para hacer la distincion de los menus de el contenido de la pagina.

greenpanel
greenpanel.jpg

Por ultimo los botones de menu.

btncuenta                                    btncuentahover

btncuenta.png                         btncuentahover.png

btnmisposts                                      btnmispostshover

btnmisposts.png                        btnmispostshover.png

btnmiscomentarios                                      btnmiscomentarioshover

btnmiscomentarios.png               btnmiscomentarioshover.png

btntodoslosposts                                        btntodoslospostshover

btntodoslosposts.png              btntodoslospostshover.png

Para todas las tablas necesitaremos imagenes de fondo y estas seran las siguientes.

whitetranspbg               redtranspbg

whitetranspbg.png                redtranspbg.png

Es importante resaltar que la mayoria de estas imagenes se han realizado en power point, esto es para facilitar la edicion de las imagenes, y principalmente agregar las transparencias, si se desea crear imagenes propias, pueden agrupar varias formas en power point y cuando haya quedado de su agrado solo le dan click derecho a el grupo de formas o imagenes y seleccionan guardar imagen como, esto facilita muchisimo el realizar botones,

Hay que considerar que los botones que se deseen colocarles el hover deben ser de las mismas dimensiones, ademas como tip, recomiendo que las imagenes que creen en power point sean pequeñas puesto que entre mas ligeras sean las imagenes mas rapida sera su pagina.

Con toda esta informacion previa podemos ahora iniciar con nuestra capa de presentacion

 

Ahora agregaremos la capa de presentacion, para esto en la solucion Foro agregaremos un nuevo proyecto como se muestra en la siguiente imagen:

//crearcapapresentacion

En la ventana de agregar nuevo proyecto, seleccionamos de los tipos de proyectos -> web y de las plantillas -> Aplicacion web ASP.NET por ultimo le asignamos el nombre de Presentacion y aceptamos, lo anterior se detalla en la siguiente imagen:

//Agregarpresentacion

Ahora con el proyecto creado, iniciaremos nuestra capa de presentacion agregando 4 elementos importantes.

  • Primero: Agregaremos las referencias a nuestra capa de Negocio.
    Para esto al igual como lo realizamos en la capa anterior daremos click derecho en referencias de nuestra capa de presentacion y despues seleccionamos agregar referencia://AgregarreferenciaEn la ventana de Agregar referencia seleccionamos la pestaña de Proyectos y seleccionamos Negocio y aceptamos.//agregarrefnegocio

  • Segundo: Crearemos la carpeta de las imagenes, para lograr esto seleccionamos nuestro proyecto de presentacion y con click derecho nos mostrara algunas opciones que podemos realizar en esta ocacion seleccionaremos la de agregar ahi podemos ver que se muestra nueva carpeta la cual seleccionaremos, lo anterior se muestra en la siguiente imagen://agregar carpetadespues de esto le asignaremos el nombre de Images el cual es el nombre estandard para esta carpeta.//carpetaimages

    en esta carpeta podemos agregar todas las imagenes que anteriormente se describieron, primero se deben descargar todas las imagenes y posteriormente se integran a Visual Studio de la siguiente manera.

    Se selecciona la carpeta Images y con click derecho se puede ver la opcion de agregar despues se puede observar la opcion de elemento existente, lo anterior se muestra en la siguiente imagen:

    //agregar imagenes

    Una vez en la ventana de Agregar elemento existente – Presentacion, se deberan agregar todas las imagenes para que resulte algo parecido a la siguiente imagen:

    //todasImagenes

  • Tercero: De la misma manera que creamos la carpeta anterior, crearemos una carpeta llamada Views, la cual contendra todas las paginas de el foro, para que nuestro usuario las pueda utilizar sera necesario que se autentifique correctamente.//carpetaviews

  • Cuarto: Se necesita otra pagina tipo web forms, la cual se necesitara para registrar a los usuarios.Para lograr esto hacemos click derecho sobre presentacion despues seleccionamos agregar y por ultimo nuevo elemento como se muestra en la siguiente imagen://agregarnuevoelemento

    Seleccionaremos de tipo web forms y la nombraremos Registro.aspx

    //crearregistroaspx

Con esto tenemos la estructura basica para empezar a realizar la pagina de login y registro de nuestra aplicacion.

Iniciaremos codificando nuestro diseño de la pagina de inicio, en el marcado de nuestra pagina Default, el cual es el archivo Default.aspx empezaremos por agregarle el titulo de Login.

<title>Login</title>

Despues le daremos un fondo a nuestra pagina, agregandole a nuestra etiqueta body la imagen anteriormente proporcionada, para que la imagen se ajuste a la pantalla se necesitan los modificadores height y width al 100% asi como tambien el background-size:cover para que se ajuste al tamaño de cuanquier resolucion de la siguiente manera:

<body style="margin: 0; padding: 0; position: absolute; height: 100%; background-color: #357EC7;

    width: 100%; background-image: url('/Images/ablue.jpg'); background-size: cover;">

 

Dentro de la etiqueta agregaremos un div el cual contendra nuestro formulario, de igual manera queremos que utilice toda la pantalla, para ello se utilizan los modificadores width y height.

<div style="position: absolute; top: 0; width: 100%; height: auto;">

Dentro del div anterior necesitaremos un panel esto es con el proposito de agregarle la funcion de ejecutar el click del boton entrar, es decir, si el usuario ingresa un enter al terminar de escribir el password, el programa automaticamente ejecuta el click del boton entrar, parece algo que podria omitirse pero muchos usuarios estamos acostumbrados a dar enter despues de introducir el password, y es un poco desconcertante dar enter y que no pase nada, si necesitas saber mas sobre esto revisa este post.

<asp:Panel ID="pandefaultbtn" runat="server" DefaultButton="btnEntrar">

<table id="esquema" runat="server" width="100%" cellpadding="0" cellspacing="0" border="0">

<td colspan="3">

   <div style="vertical-align: top">

      <asp:Image ID="Image2" ImageUrl="~/Images/header.png" runat="server" Height="120px" Width="100%" />

      <br />

      <br />

   </div>

</td>

 

<td>

   <div style="width: 500px; margin-right: 0px;">

   </div>

</td>

<td style="text-align: right">

   <asp:Label ID="lblusuario" runat="server" Text="Usuario" Font-Names="Impact" Font-Size="Large"/>                       

   </asp:Label>

</td>

<td>

     

   <asp:TextBox ID="txtusuario" runat="server"></asp:TextBox>

</td>

 

<td colspan="2" style="text-align: right">

   <asp:Label ID="lblpassword" runat="server" Text="Password" Font-Size="Large" Font-Names="Impact"></asp:Label>

</td>

<td>

     

   <asp:TextBox ID="txtPassword" TextMode="Password" runat="server"></asp:TextBox>

</td>

 

<td style="text-align: center" align="center" colspan="2">

   <asp:Label ID="lblMsg" runat="server" Font-Names="Impact" Font-Overline="False" Font-Strikeout="False" ForeColor="Maroon"></asp:Label>

</td>

 

 

 

<td colspan="2" style="text-align: right">

<br />

   <asp:ImageButton ID="btnRegistrar" ImageUrl="~/Images/btnregistrar_normal.png" onmouseover="src='./Images/btnregistrar_over.png'" 0nmouseout="src='./Images/btnregistrar_normal.png'" runat="server" Height="40px" Width="150px" OnClick="btnRegistrar_Click" />

</td>

<td>

   <br />

   <asp:ImageButton ID="btnEntrar" ImageUrl="~/Images/btnentrar_normal.png"  onmouseover="src='./Images/btnentrar_over.png'" onmouseout="src='./Images/btnentrar_normal.png'" runat="server" Height="40px" Width="134px" OnClick="btnEntrar_Click" />

</td>

 

 

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Presentacion._Default" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<head runat="server">

    <title>Login</title>

</head>

<body style="margin: 0; padding: 0; position: absolute; height: 100%; background-color: #357EC7;

    width: 100%; background-image: url('/Images/ablue.jpg'); background-size: cover;">

    <form id="form1" runat="server">

    <div style="position: absolute; top: 0; width: 100%; height: auto;">

        <asp:Panel ID="pandefaultbtn" runat="server" DefaultButton="btnEntrar">

            <table id="esquema" runat="server" width="100%" cellpadding="0" cellspacing="0" border="0">

                <tr>

                    <td colspan="3">

                        <div style="vertical-align: top">

                            <asp:Image ID="Image2" ImageUrl="~/Images/header.png" runat="server"                                           Height="120px" Width="100%" />

                            <br />

                            <br />

                        </div>

                    </td>

                </tr>

                <tr>

                    <td>

                        <div style="width: 500px; margin-right: 0px;">

                        </div>

                    </td>

                    <td style="text-align: right">

                        <asp:Label ID="lblusuario" runat="server" Text="Usuario" Font-Names="Impact" Font-Size="Large"></asp:Label>

                    </td>

                    <td>

                          

                        <asp:TextBox ID="txtusuario" runat="server"></asp:TextBox>

                    </td>

                </tr>

                <tr>

                    <td colspan="2" style="text-align: right">

                        <asp:Label ID="lblpassword" runat="server" Text="Password" Font-Size="Large" Font-Names="Impact"></asp:Label>

                    </td>

                    <td>

                          

                        <asp:TextBox ID="txtPassword" TextMode="Password" runat="server"></asp:TextBox>

                    </td>

                </tr>

                <tr>

                    <td style="text-align: center" align="center" colspan="2">

                        <asp:Label ID="lblMsg" runat="server" Font-Names="Impact" Font-Overline="False" Font-Strikeout="False"

                            ForeColor="Maroon"></asp:Label>

                    </td>

                </tr>

                <tr>

                    <td colspan="2" style="text-align: right">

                        <br />

                        <asp:ImageButton ID="btnRegistrar" ImageUrl="~/Images/btnregistrar_normal.png" onmouseover="src='./Images/btnregistrar_over.png'"

                            onmouseout="src='./Images/btnregistrar_normal.png'" runat="server" Height="40px"

                            Width="150px" OnClick="btnRegistrar_Click" />

                    </td>

                    <td>

                        <br />

                        <asp:ImageButton ID="btnEntrar" ImageUrl="~/Images/btnentrar_normal.png" onmouseover="src='./Images/btnentrar_over.png'"

                            onmouseout="src='./Images/btnentrar_normal.png'" runat="server" Height="40px"

                            Width="134px" OnClick="btnEntrar_Click" />

                    </td>

                </tr>

            </table>

        </asp:Panel>

    </div>

    </form>

</body>

</html>

 

–using Negocio

using System;

using System.Collections;

using System.Configuration;

using System.Data;

using System.Linq;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Linq;

using Negocio;

 

namespace Presentacion

{

    public partial class _Default : System.Web.UI.Page

    {

        protected void Page_Load(object sender, EventArgs e)

        {

            if (!string.IsNullOrEmpty((string)Session["StatusMessage"]))

            {

                string mensaje = (string)Session["StatusMessage"];

                // Clear the session variable

                Session["StatusMessage"] = null;

                // Enable some control to display the message (control is likely on the master page)

                System.Web.HttpContext.Current.Response.Write("<script type="text/javascript" language="\"JavaScript\"">// <![CDATA[

alert(\""+mensaje+"\")

// ]]></script>");

 }

 }

 

 protected void btnRegistrar_Click(object sender, ImageClickEventArgs e)

 {

 Session["CrearUsuario"] = "Valido";

 Response.Redirect("~/Registro.aspx");

 }

 

 protected void btnEntrar_Click(object sender, ImageClickEventArgs e)

 {

 if (AccesoLogica.verificaUsuario(txtusuario.Text, txtPassword.Text))

 {

 Session["Start"] = 0;

 Session["Nombre"] = txtusuario.Text;

 Response.Redirect("~/Views/Perfil.aspx");

 }

 else

 {

 lblMsg.Text = "Password o Usuario incorrecto";

 }

 }

 }

}

 

 

 

 

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Registro.aspx.cs" Inherits="Presentacion.Registro" %>

 

Registro

 

</pre>

<form id="form1">

<div style="position: absolute; top: 0; width: 100%; height: auto;">

<table id="esquema" width="100%" border="0" cellspacing="0" cellpadding="0">

<tbody>

<tr>

<td colspan="2"></td>

</tr>

<tr>

<td style="text-align: center;" colspan="2">

</td>

</tr>

<tr>

<td style="text-align: right;"></td>

<td>

</td>

</tr>

<tr>

<td style="text-align: right;"></td>

<td>

</td>

</tr>

<tr>

<td style="text-align: right;"></td>

<td>

</td>

</tr>

<tr>

<td style="text-align: right;"></td>

<td>

</td>

</tr>

<tr>

<td style="text-align: right;"></td>

<td>

 

</td>

</tr>

<tr>

<td style="text-align: right;"></td>

<td>

 

</td>

</tr>

<tr>

<td style="text-align: right;"></td>

<td>

</td>

</tr>

<tr>

<td style="text-align: right;"></td>

<td>

</td>

</tr>

<tr>

<td style="text-align: right;">

 

</td>

<td style="text-align: left;">

 

</td>

</tr>

<tr>

<td style="text-align: center;" colspan="2">

 

</td>

</tr>

</tbody>

</table>

</div>

</form>

<pre>

using System;

using System.Collections;

using System.Configuration;

using System.Data;

using System.Linq;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Linq;

using Negocio;

 

namespace Presentacion

{

    public partial class Registro : System.Web.UI.Page

    {

        protected void Page_Load(object sender, EventArgs e)

        {

            string registro;

            try

            {

                registro = Session["CrearUsuario"].ToString();

            }

            catch

            {

                registro = "";

            }

            if (registro != "Valido")

            {

                Response.Redirect("~/Default.aspx");

            }

            string[] arrPais = new string[] { "Antigua y Barbuda", "Argentina", "Bahamas", "Barbados", "Belice", "Bolivia", "Brasil", "Canada", "Chile", "Colombia", "Costa Rica", "Cubanica", "Ecuador", "El Salvador", "Estados Unidos", "Granada", "Guatemala", "Guyana", "Haití", "Honduras", "Jamaica", "México", "Nicaragua", "Panamá", "Paraguay", "Perú", "República Dominicana", "Santa Lucía", "San Cristóbal y Nieves", "San Vicente y las Granadinas", "Surinam", "Trinidad y Tobago", "Uruguay", "Venezuela" };

            for (int i = 0; i < arrPais.Count(); i++)

                ddlPais.Items.Add(arrPais[i]);

 

            ddlSexo.Items.Add(new ListItem("Femenino", "F"));

            ddlSexo.Items.Add(new ListItem("Masculino", "M"));

 

        }

 

        protected void btnCancelar_Click(object sender, ImageClickEventArgs e)

        {

            Session["CrearUsuario"] = null;

            Response.Redirect("~/Default.aspx");

        }

 

        protected void btnListo_Click(object sender, ImageClickEventArgs e)

        {

            int flag = 0;

            string msg = "";

            if (txtusuario.Text == "")

            {

                msg += "El campo usuario esta vacio

";

                flag++;

            }

            if (txtPassword.Text == "")

            {

                msg += "El campo password esta vacio

";

                flag++;

            }

            if (txtNombre.Text == "")

            {

                msg += "El campo nombre esta vacio

";

                flag++;

            }

            if (txtApellido.Text == "")

            {

                msg += "El campo apellido esta vacio

";

                flag++;

            }

            if (txtcorreo.Text == "")

            {

                msg += "El campo correo esta vacio

";

                flag++;

            }

            if (txtTelefono.Text == "")

            {

                msg += "El campo telefono esta vacio

";

                flag++;

            }

 

            if (flag != 0)

            {

                lblMsg.Text = msg;

            }

            else

            {

                if (AccesoLogica.InsertarUsuario(txtusuario.Text, txtPassword.Text, txtNombre.Text, txtApellido.Text, ddlPais.SelectedIndex, char.Parse(ddlSexo.SelectedValue.ToString()), txtcorreo.Text, txtTelefono.Text))

                {

                    Session["StatusMessage"] = "El registro se realizo satisfactoriamente, Ingrese sus datos para loguearse";

                    Session["CrearUsuario"] = null;

                    Response.Redirect("Default.aspx");

                }

                else

 

                    lblMsg.Text = "El usuario ya existe intente con otro usuario";

                    Session["CrearUsuario"] = null;

            }

 

        }

 

    }

}

 

 

En el siguiente link les comparto el Código Completo para la aplicación antes descrita.

 

 

 

 

Volver

 

 

*