Curso sobre programacion c# y Visual Studio 2019. En este blog veremos tutoriales para aprender a crear nuestras aplicaciones de consola,aplicaciones web, SQL , Tensorflow y Machine Learning
39-. Aplicaciones web. Autenticación.Carrito de compra(2)
- En este capítulo del curso de programación en c# con visual studio
2017,vamos a crear un mecanismo de autenticación. Ya teniamos hecho en entradas anteriores del blog la validación contra nuestra base de datos.Esta nueva validación añadida a la que ya teniamos hecha previamente, nos servirá para controlar que páginas mostamos a los usuarios que esten logados y que páginas son de aceso público.
- Además como muestro en el video , aprovecharemos para generar las cookies y datos necesarios para poder generar un pedido con el usuario que inicio sesión en nuestro sitio de pruebas.
- En este capítulo del curso de programación en c# con visual studio
2017,vamos a empezar a crear el mecanismo necesario para que el usuario pueda hacer compras en nuestro proyecto de pruebas.Ya teniamos en nuestra página de pedidos un control de Treeview en el que mostrabamos todos los productos disponibles en nuestra base de datos.
- En este video os explico como traer y mostrar los datos del producto que seleccionemos en nuestro árbol.Si recordaís cuando cargabamos el TreeView via procedimiento almacenado, además del valor que mostramos en pantalla guardamos el idproducto en el valor de cada nodo del árbol. Ahora podemos utilizar este id de producto para mostrar los datos del producto seleccionado en pantalla:
- Vamos a poner paso a paso el código visto en el video:
Añadimos en nuestra página web Pedidos.aspx los crontroles necesarios para mostrar los datos del producto seleccionado.
private void CargarDatosProducto(string idProducto)
{
SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
- En este capítulo del curso de programación en c# con visual studio
2017,vamos a ver un control de uso común en muchas de las páginas web
que utilizamos habitualmente.Hablo del UpdateProgress , que para que funcione correctamente debe estar ubicada dentro de un UpdatePanel.Os dejo dos pinceladas de estos dos controles:
UpdatePanel: Los controles UpdatePanel
permiten actualizar las partes seleccionadas de una página en lugar de
actualizar toda la página con una devolución de datos. Esto se conoce
como actualización parcial de la página.
UpdateProgress: El control UpdateProgress proporciona información de estado sobre las actualizaciones parciales de página en controles UpdatePanel
. Puede personalizar el contenido y el diseño predeterminados del control UpdateProgress.
Para evitar el parpadeo que se produce cuando una actualización parcial
de página es muy rápida, puede especificar un retraso antes de que se
muestre el control UpdateProgress.
- Veamos un ejemplo en el video:
* Como hago habitualmente os dejo el código del ejemplo tantode la parte de cliente como de la parte de servidor:
- En este capítulo del curso de programación en c# con visual studio
2017,continuamos con un poco de SQL SERVER y además veremos como cargar el control Treeview a partir de los productos que tenemos almacenados en nuestra base de datos de pruebas.
- Normalmente el control TreeView se compone de uno o varios nodos. Cada entrada del árbol se denomina nodo y se representa mediante un objeto TreeNode. Tenemos tres tipos de nodos:
Raiz: Nodo que no tiene ningún nodo primario y tiene uno o varios nodos secundarios.
Principal: Un nodo que tiene un nodo primario y uno o varios nodos secundarios.
Hoja: Un nodo que no tiene ningún nodo secundario.
- En el siguiente video podéis ver como cargar un control TreeView desde nuestro origen de datos que es nuestra base de datos de pruebas.
- Os dejo el código paso a paso de lo mostrado en el video:
Primero cargamos nuestra tabla de productos.En ella definmos 7 productos padre de los que colgaran el resto de productos.
En segundo lugar nos creamos un procedimiento almacenado y una función que nos permita recuperar los datos de la manera adecuada para el control TreeView. Este es el código de ambos:
IF(@idProducto is NULL)
BEGIN
SELECT IdProducto,Nombre FROM PRODUCTOS WHERE idPAdre IS NULL
END
ELSE
BEGIN
DECLARE @TablaTemp2 TABLE(IdTemp int NOT NULL)
INSERT INTO @TablaTemp2 SELECT * FROM DameIdHijos(@idProducto)
SELECT IdProducto,Nombre,idPadre FROM @TablaTemp2 as tabla
INNER JOIN PRODUCTOS ON Productos.IdProducto = tabla.IdTemp and idPadre is not null
END
END
* Función:
ALTER FUNCTION [dbo].[DameIdHijos](@IdPadre int)
RETURNS @Tabla TABLE (IdTemp int NOT NULL)
AS
BEGIN
DECLARE @TablaTemp2 TABLE(IdTemp int NOT NULL, Analizado bit)
-- Si no se especifica un IdPadre entonces ERROR. Devolvemos NADA
IF @IdPadre is null
BEGIN
RETURN
END
DECLARE @IdPadreTemp int
INSERT INTO @TablaTemp2 SELECT IdProducto,0 FROM PRODUCTOS WITH (NOLOCK) WHERE IdProducto=@IdPadre OR IdProducto=@IdPadre
SELECT TOP 1 @IdPadreTemp=IdTemp FROM @TablaTemp2 WHERE Analizado=0 ORDER BY IdTemp
WHILE NOT @IdPadreTemp IS NULL
BEGIN
SET @IdPadreTemp=NULL
SELECT TOP 1 @IdPadreTemp=IdTemp FROM @TablaTemp2 WHERE IdTemp IN (SELECT DISTINCT IdPadre FROM PRODUCTOS WITH (NOLOCK) WHERE IdPadre IN (SELECT IdTemp FROM @TablaTemp2 WHERE Analizado=0) AND Analizado=0)
IF not @IdPadreTemp is null
BEGIN
INSERT INTO @TablaTemp2 SELECT IdProducto,0 FROM PRODUCTOS WITH (NOLOCK) WHERE IdPadre=@IdPadreTemp
UPDATE @TablaTemp2 SET Analizado=1 WHERE IdTemp=@IdPadreTemp
END
END
INSERT INTO @Tabla (IdTemp)
SELECT DISTINCT IdTemp FROM @TablaTemp2
RETURN
END
En tercer lugar necesitamos llamar a nuestro procedimiento almacenado desde nuestra página web para cargar los datos en nuestro TreeView.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace GestionVarios
{
public partial class Pedidos : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
InicializarDatos();
}
}
private void InicializarDatos()
{
SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
try
{
Con.Open();
SqlCommand Com = Con.CreateCommand();
Com.CommandText = "DameHijosArbolPorProducto";
Com.CommandType = CommandType.StoredProcedure;
SqlDataReader Rst = Com.ExecuteReader();
int i = 0;
while (Rst.Read())
{
treeViewProductos.Nodes.Add(new TreeNode());
treeViewProductos.Nodes[i].Text = Rst["Nombre"].ToString();
treeViewProductos.Nodes[i].Value = Rst["IdProducto"].ToString();
cargarHijos(Rst["IdProducto"].ToString(),i);
i++;
}
Rst.Close();
//Expande todos los nodos
treeViewProductos.ExpandAll();
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
finally
{
if (Con.State == ConnectionState.Open)
Con.Close();
Con.Dispose();
}
- En este capítulo del curso de programación en c# con visual studio
2017,continuamos con un poco de SQL SERVER. Para ello debéis tener instalado SQL Express. En entradas anteriores del blog tenéis el enlace de descarga.
- En nuestra base de datos de prueba teníamos hasta ahora definidas dos tablas: una tabla Usuarios donde tenemos almacenados los usuarios dados de alta en la aplicación y una tabla Paises donde almacenamos los distintos paíes que admite nuestro sistema.
- En este capítulo del blog hemos añadido tres tablas nuevas: Pedidos,Pedidos_Lineas y Productos. El objetivo es crear una estructura de tablas que nos permita almacenar diferentes pedidos que el usuario haga desde la aplicación.En esta imagen podéis ver el diagrama:
- En la tabla Pedidos almacenaremos los pedidos que cada usuario haga en la web.Está relaccionada con la tabla Usuarios por el campo idUsuario para poder obtener de una manera fácil los 1 o n pedidos que los usuario hagan. A su vez la tabla Pedidos la relaccionamos con la tabla Productos a traves de la tabla Pedidos_lineas , de esta forma identificamos a través del campo idpedido todos los productos que tenga asociados.
- Os propongo un ejemplo para que entendáis para que hacer esta estrutura de tablas. Supongamos que queremos saber cuantos pedidos del produtco X ha hecho el usuario Y. Al estar la tablas relacionadas podemos obtener los datos fácilmente con una consulta como por ejemplo la siguiente:
SELECT count(*) FROM Usuarios INNER JOIN PEDIDOS ON PEDIDOS.IdUsuario = Usuarios.IdUsuarios INNER JOIN Pedido_Lineas ON Pedido_Lineas.IdPedido = Pedidos.IdPedido INNER JOIN Productos ON Pedido_Lineas.IdProducto = Productos.IdProducto WHERE email='el que sea' and Productos.Sku='SKU QUE SEA'
- En este capítulo del curso de programación en c# con visual studio
2017vamos a ver como crear una página maestra para un sitio web.Las páginas maestras de ASP.NET
permiten crear un diseño común para las páginas de la aplicación.
Puede definir el aspecto, el diseño y el comportamiento estándar que
desea que tengan todas las páginas (o un grupo de páginas) de la
aplicación en una sola página maestra.
- La página maestra define la apariencia de las páginas del sitio.Puede contener cualquier combinación de texto estático y controles.Una
página maestra también contiene marcadores de posición de
contenido que indican dónde aparecerá el contenido dinámico cuando se
muestren las páginas.
- En este capítulo del curso de programación en c# con visual studio
2017vamos a ver como crear unmecanismo para actualizar passwords que tengamos almacenadas en una base de datos.Para ello generamos una url con el email del usuario cifrado que pondremos como parametro en la querystring, y creamos otra página que valide y actualice en base de datos. Los pasos para cambiar la password son los siguientes:
El usuario hace click en el enlace ¿Olvido su contraseña?
Al hacer click solicitamos un email con el que validaremos que usuario existe en nuestro el sistema.
En el caso que el usuario exista generamos una url con el email cifrado incrustado en ella como parametro encriptado.Esta url apuntará a una página que tenemos creada para actualizar la password en la base de datos.
Esta url debería llegar al usuario via email.
Cuando el usuario hace clic en esta url validamos el email que nos llega encriptado no ha sido alterado (esta comprobación la hacemos para evitar en la medida de lo posble los bot y ataques varios).
Si todo es correcto apareceran en pantalla dos cajas de texto donde el usuario debe poner la nueva password.
Despues de poner la password pulsando el botón actualizaremos en la base de datos.
- En el video muestro como se hacen estos pasos:
- Os dejo el código completo del ejmplo del Login:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Net.Mail;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace GestionVarios
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// CODIGO QUE ENVIARIA UN MAIL CON LA URL.ESTA HECHO EN EL KEYLOGGER
lblErrorREcordar.Text = url + "//" + Request.Url.Host +":"+Request.Url.Port+ "/RecuperarPass.aspx?p=" + encoded ;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace GestionVarios
{
public partial class RecuperarPass : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string mail = obtenerMail();
validarEmail(mail);
}
private string obtenerMail()
{
byte[] byteArray = Convert.FromBase64String(Request.QueryString["p"]);
string value = System.Text.Encoding.UTF8.GetString(byteArray);
String miclave = ConfigurationManager.AppSettings["clave"];
byte[] claveCifrado = System.Text.Encoding.ASCII.GetBytes(miclave);
Cifrado c = new Cifrado(claveCifrado);
string mail = c.descifrar(byteArray);
return mail;
}
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(cadena);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
private string DesencriptarStringFromBytesAes(byte[] textoCifrado, byte[] clave, byte[] IV)
{
if (textoCifrado == null || textoCifrado.Length <= 0)
throw new ArgumentNullException("cipherText");
if (clave == null || clave.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
string plaintext = null;
using (MemoryStream msDecrypt = new MemoryStream(textoCifrado))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
plaintext = srDecrypt.ReadToEnd();