Pop

40-. Aplicaciones web. ViewState.Carrito de compra(3).Curso de C# con Visual Studio 2017.

40-. Aplicaciones web. ViewState.Carrito de compra(3)

  - En este capítulo del curso de programación en c# con visual studio 2017,vamos empezar a utilizar el ViewState. Lo utilizaremos para almacenar los productos seleccionados por el usuario en cada petición al servidor.Si no utlizaramos este u otro mecanismo en cada ida y vuelta perderiamos los datos.

-  Para comprender el funcionamiento de los métodos explicados en el video, es necesario conocer el ciclo de vida de una página,que ya fue explicado en entradas anteriores.Como podeís ver en la imagen.  los datos del ViewState se cargan antes de pasar por el evento Load y se guardan antes de renderizar la página. Como los métodos que cargan y guardan el ViewState permiten ser sobreescritos utilizando el modificador override los modificamos para guardar y cargar los prodcutos que el usaurio vaya seleccionando.


 - Una vez comprendido en que momentos se llaman a los métodos que utilizan el ViewsState os dejo el video donde utilizo este mecanismo:


- Os dejo un enlace a la MSDN para completar la información:https://msdn.microsoft.com/es-es/library/bb386448(v=vs.100).aspx

- También os dejo el código de lo visto en en el video:

  • Código de la página Pedido.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Pedidos.aspx.cs" Inherits="GestionVarios.Pedidos" MasterPageFile="~/Master.Master" %>

<asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server">


    <div style="background-color: #FFFFFF">
        <table>
            <tr>
                <td align="left" width="30%">
                    <asp:TreeView ID="treeViewProductos" runat="server" OnSelectedNodeChanged="treeViewProductos_SelectedNodeChanged"></asp:TreeView>

                </td>
                <td align="center"  width="50%">
                   
                    <asp:Label ID="lblNombreProducto" runat="server"></asp:Label><br />
                    <asp:Label ID="lblDescripcion" runat="server"></asp:Label><br />
                    <asp:Label ID="lblPrecioDeCompra" runat="server"></asp:Label><br />
                    <asp:Label ID="lblCantidad" runat="server" Text="Unidades:" Visible="false"></asp:Label>
                    <asp:TextBox runat="server" ID="txtUnidades" Width="40px" Visible="false"></asp:TextBox>
                      <asp:RequiredFieldValidator ID="mreqEMail" runat="server" ControlToValidate="txtUnidades" ErrorMessage="*" Display="Dynamic" ForeColor="Red"  ></asp:RequiredFieldValidator><br />
                    <asp:RegularExpressionValidator ID="mregEMail" runat="server" ControlToValidate="txtUnidades" ErrorMessage="Introduzca un numero" ValidationExpression="^\d+$" Display="Dynamic"  ForeColor="Red"></asp:RegularExpressionValidator>
      
                  
                </td>
                <td  width="20%">

                    <asp:Button id="btnAgregar" runat="server" Text="Agregar al carro" Visible="false" OnClick="btnAgregar_Click"/>
                 
                </td>
                   <td  width="20%">

                     <asp:Button ID="btnVerCompra" runat="server" Text="Ver carro compra" OnClick="btnVerCompra_Click"  Visible="false"/>
                 
                </td>
           </tr>
        </table> 
   </div>
</asp:Content>

  •  Código de la página Pedido.aspx.cs
 using System;
using System.Collections;
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
    {
        private ArrayList productosSeleccionados = new ArrayList();
            
     
        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.CollapseAll();//.ExpandAll();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            finally
            {
                if (Con.State == ConnectionState.Open)
                    Con.Close();
                Con.Dispose();
            }

        }

        private void cargarHijos(string idProducto,int posicionNodo)
        {

            SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
            string IdPadre = String.Empty;
            IdPadre = idProducto;
            try
            {
                Con.Open();
                SqlCommand Com = Con.CreateCommand();
                Com.CommandText = "DameHijosArbolPorProducto";
                Com.CommandType = CommandType.StoredProcedure;
                Com.Parameters.Add("@idProducto", SqlDbType.Int).Value = idProducto;
                SqlDataReader Rst = Com.ExecuteReader();
           

                while (Rst.Read())
                {
                    TreeNode Tn = new TreeNode();
                    Tn.Text = Rst["Nombre"].ToString();
                    Tn.Value = Rst["IdProducto"].ToString();


                    if (Rst["IdPadre"].ToString() != IdPadre)
                    {
                        TreeNode Padre = DameNodoPorId(treeViewProductos.Nodes[posicionNodo], Rst["IdPadre"].ToString());
                        Padre.ChildNodes.Add(Tn);
                    }
                    else
                    {
                        treeViewProductos.Nodes[posicionNodo].ChildNodes.Add(Tn);
                    }
                }

                Rst.Close();
                Com.Dispose();


            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            finally
            {
                if (Con.State == ConnectionState.Open)
                    Con.Close();
                Con.Dispose();
            }
        }

        private TreeNode DameNodoPorId(TreeNode Nodo, string Id)
        {
            if (Nodo.Value == Id)
                return Nodo;

            for (int i = 0; i < Nodo.ChildNodes.Count; i++)
            {
                if (Nodo.ChildNodes[i].Value == Id)
                    return Nodo.ChildNodes[i];

                TreeNode RetNodo = DameNodoPorId(Nodo.ChildNodes[i], Id);

                if (RetNodo != null)
                    return RetNodo;
            }
            return null;
        }

        protected void treeViewProductos_SelectedNodeChanged(object sender, EventArgs e)
        {
            TreeNode nodo = treeViewProductos.SelectedNode;
            CargarDatosProducto(nodo.Value);
            btnAgregar.Visible = true;
            txtUnidades.Visible = true;
            lblCantidad.Visible = true;
        }

        private void CargarDatosProducto(string idProducto)
        {
            SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);

            try
            {
                Con.Open();
                SqlCommand Com = Con.CreateCommand();
                Com.CommandText = "DameDatosProducto";
                Com.CommandType = CommandType.StoredProcedure;
                Com.Parameters.Add("@idProducto", SqlDbType.Int).Value = idProducto;
                SqlDataReader Rst = Com.ExecuteReader();


                while (Rst.Read())
                {
                    lblDescripcion.Text = "Detalles producto" + Rst["Descripcion"].ToString();
                    lblNombreProducto.Text = "Producto: " + Rst["Nombre"].ToString();
                    lblPrecioDeCompra.Text = "Precio por unidad:" + Rst["PrecioVenta"].ToString() + " € ";
                }

                Rst.Close();
                Com.Dispose();


            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            finally
            {
                if (Con.State == ConnectionState.Open)
                    Con.Close();
                Con.Dispose();
            }
        }

        protected void btnAgregar_Click(object sender, EventArgs e)
        {

            btnVerCompra.Visible = true;
            TreeNode nodo = treeViewProductos.SelectedNode;
            productosSeleccionados.Add(nodo.Value);
            productosSeleccionados.Add(txtUnidades.Text);
       
        }


        protected override void LoadViewState(object savedState)
        {
           base.LoadViewState(savedState);
           this.productosSeleccionados = (ArrayList)this.ViewState["productosCarro"];
        }


        protected override object SaveViewState()
        {
            this.ViewState.Add("productosCarro", productosSeleccionados);

            return base.SaveViewState();

        }

        protected void btnVerCompra_Click(object sender, EventArgs e)
        {
          
        }
    }
}

39.Aplicaciones web.Autenticacion.Carrito de compra(2). Curso de C# con Visual Studio 2017.

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 el siguiente enlace os dejo información más detallada sobre el como implementar la autenticación de formularios simple:https://msdn.microsoft.com/es-es/library/xdt4thhy(v=vs.100).aspx

* Para ver más claro el ejemplo os pongo por escrito los pasos vistos en el video para poder utilizar este tipo de autenticación:

  1.  Añadimos en fichero de configuración web.config el tipo de autenticación y las de las páginas a las que afecta:
   <system.web>
    <authentication mode="Forms">
       <forms loginUrl="Default.aspx" name=".ASPXFORMSAUTH" path="/" defaultUrl="~/Premium/Default.aspx" slidingExpiration="false" enableCrossAppRedirects="false" timeout="3600"/>
    </authentication>
  </system.web>

   <location path="Premium">
    <system.web>
      <authorization>
        <deny users="?"/>
      </authorization>
    </system.web>
  </location>

  2. Una vez que tenemos el usuario validado contra nuestra base de datos generamos una cookie:

    private void crearCookie(String email, int idUsuario)
        {
      
                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(email, false, 60);
                string ticketEncriptado = FormsAuthentication.Encrypt(ticket);
                HttpCookie SesionUsuario = new HttpCookie("Cookie", ticketEncriptado);
                SesionUsuario.Expires = DateTime.Now.AddDays(366);
                HttpContext.Current.Response.Cookies.Add(SesionUsuario);
                FormsAuthentication.RedirectFromLoginPage(idUsuario.ToString(), false);
            
   }

3. Ya tenemos diponible el idusuario que vamos a utilizar para generar el pedido:

 Convert.ToInt32(HttpContext.Current.User.Identity.Name);

38.Aplicaciones web.Carrito de compra(1). Curso de C# con Visual Studio 2017.

38- . Aplicaciones web. Carrito de compra(1)

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

  1. Añadimos en nuestra página web Pedidos.aspx los crontroles necesarios para mostrar los datos del producto seleccionado.
 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Pedidos.aspx.cs" Inherits="GestionVarios.Pedidos" MasterPageFile="~/Master.Master" %>

<asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server">


    <div style="background-color: #FFFFFF">
        <table>
            <tr>
                <td align="left" width="30%">
                    <asp:TreeView ID="treeViewProductos" runat="server" OnSelectedNodeChanged="treeViewProductos_SelectedNodeChanged"></asp:TreeView>

                </td>
                <td align="center"  width="50%">
                  
                    <asp:Label ID="lblNombreProducto" runat="server"></asp:Label><br />
                    <asp:Label ID="lblDescripcion" runat="server"></asp:Label><br />
                    <asp:Label ID="lblPrecioDeCompra" runat="server"></asp:Label><br />
                    <asp:Label ID="lblCantidad" runat="server" Text="Unidades:" Visible="false"></asp:Label>
                    <asp:TextBox runat="server" ID="txtUnidades" Width="40px" Visible="false"></asp:TextBox>
                      <asp:RequiredFieldValidator ID="mreqEMail" runat="server" ControlToValidate="txtUnidades" ErrorMessage="*" Display="Dynamic" ForeColor="Red"  ></asp:RequiredFieldValidator><br />
                    <asp:RegularExpressionValidator ID="mregEMail" runat="server" ControlToValidate="txtUnidades" ErrorMessage="Introduzca un numero" ValidationExpression="^\d+$" Display="Dynamic"  ForeColor="Red"></asp:RegularExpressionValidator>
     
                 
                </td>
                <td  width="20%">

                    <asp:Button id="btnAgregar" runat="server" Text="Agregar al carro" Visible="false" OnClick="btnAgregar_Click"/>
                </td>
            </tr>
        </table>

    </div>
</asp:Content>

  2. En el fichero Pedidos.aspx.cs implementamos el evento del Treeview SelectNodeChanged para poder traer los datos de cada producto:

    protected void treeViewProductos_SelectedNodeChanged(object sender, EventArgs e)
        {
            TreeNode nodo = treeViewProductos.SelectedNode;
            CargarDatosProducto(nodo.Value);
            btnAgregar.Visible = true;
            txtUnidades.Visible = true;
            lblCantidad.Visible = true;
        }

        private void CargarDatosProducto(string idProducto)
        {
            SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);

            try
            {
                Con.Open();
                SqlCommand Com = Con.CreateCommand();
                Com.CommandText = "DameDatosProducto";
                Com.CommandType = CommandType.StoredProcedure;
                Com.Parameters.Add("@idProducto", SqlDbType.Int).Value = idProducto;
                SqlDataReader Rst = Com.ExecuteReader();


                while (Rst.Read())
                {
                    lblDescripcion.Text = "Detalles producto" + Rst["Descripcion"].ToString();
                    lblNombreProducto.Text = "Producto: " + Rst["Nombre"].ToString();
                    lblPrecioDeCompra.Text = "Precio por unidad:" + Rst["PrecioVenta"].ToString() + " € ";
                }

                Rst.Close();
                Com.Dispose();


            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            finally
            {
                if (Con.State == ConnectionState.Open)
                    Con.Close();
                Con.Dispose();
            }
        }

3. Creamos un procedimiento almacenado en SQL que nos devuelva los datos del producto seleccionado:


ALTER PROCEDURE [dbo].[DameDatosProducto]
   
    @idProducto int
AS
BEGIN

    SET NOCOUNT ON;

        SELECT Nombre,PrecioVenta,Descripcion FROM PRODUCTOS WHERE IdProducto=@idProducto;


END


37.Aplicaciones web.Control UpdateProgress.Curso de C# con Visual Studio 2017.

37- . Aplicaciones web. Control UpdateProgress

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

  • Código del fichero aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ProgessBar.aspx.cs" Inherits="GestionVarios.ProgessBar" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
         <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>

        <fieldset style="width:200px">
        <legend>Ejemplo progres bar</legend>
      
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>

        <asp:Button ID="btnSubmit" runat="server" Text="Submit"
            onclick="btnSubmit_Click" /><asp:Label ID="lblStatus"
            runat="server" Text=""></asp:Label>
                                 <asp:UpdateProgress ID="UpdWaitImage" runat="server"  DynamicLayout="true" AssociatedUpdatePanelID="UpdatePanel1">
                 <ProgressTemplate>
                                 <asp:Image ID="imgProgress" ImageUrl="imagenes/Loading_icon.gif" runat="server" />
                                                Por favor espere...
                                </ProgressTemplate>
                                </asp:UpdateProgress>     
    </ContentTemplate>
        </asp:UpdatePanel>
        </fieldset>
    </form>
</body>
</html>

  • Código del fichero cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace GestionVarios
{
    public partial class ProgessBar : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnSubmit_Click(object sender, EventArgs e)
        {
          
            System.Threading.Thread.Sleep(10000);
            lblStatus.Text = "Completado";
        }
    }
}

36.Aplicaciones web.SQL Parte 4 y Treeview.Curso de C# con Visual Studio 2017.

36- . Aplicaciones web. SQL Parte 4 y TreeView

   - 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:
                      * Procedimiento almacenado:

 CREATE PROCEDURE [dbo].[DameHijosArbolPorProducto]
  
    @idProducto int=NULL
AS
BEGIN

    SET NOCOUNT ON;

    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.
                * Código de la parte cliente:

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Pedidos.aspx.cs" Inherits="GestionVarios.Pedidos" MasterPageFile="~/Master.Master" %>
<asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
   
       <div style="background-color:#FFFFFF">
           <asp:TreeView ID="treeViewProductos" runat="server"></asp:TreeView>
          
        </div>
   </asp:Content>

                * Código de la parte de servidor:

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();
            }

        }

        private void cargarHijos(string idProducto,int posicionNodo)
        {

            SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
            string IdPadre = String.Empty;
            IdPadre = idProducto;
            try
            {
                Con.Open();
                SqlCommand Com = Con.CreateCommand();
                Com.CommandText = "DameHijosArbolPorProducto";
                Com.CommandType = CommandType.StoredProcedure;
                Com.Parameters.Add("@idProducto", SqlDbType.Int).Value = idProducto;
                SqlDataReader Rst = Com.ExecuteReader();
            

                while (Rst.Read())
                {
                    TreeNode Tn = new TreeNode();
                    Tn.Text = Rst["Nombre"].ToString();
                    Tn.Value = Rst["IdProducto"].ToString();


                    if (Rst["IdPadre"].ToString() != IdPadre)
                    {
                        TreeNode Padre = DameNodoPorId(treeViewProductos.Nodes[posicionNodo], Rst["IdPadre"].ToString());
                        Padre.ChildNodes.Add(Tn);
                    }
                    else
                    {
                        treeViewProductos.Nodes[posicionNodo].ChildNodes.Add(Tn);
                    }
                }

                Rst.Close();
                Com.Dispose();


            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
            finally
            {
                if (Con.State == ConnectionState.Open)
                    Con.Close();
                Con.Dispose();
            }
        }

        private TreeNode DameNodoPorId(TreeNode Nodo, string Id)
        {
            if (Nodo.Value == Id)
                return Nodo;

            for (int i = 0; i < Nodo.ChildNodes.Count; i++)
            {
                if (Nodo.ChildNodes[i].Value == Id)
                    return Nodo.ChildNodes[i];

                TreeNode RetNodo = DameNodoPorId(Nodo.ChildNodes[i], Id);

                if (RetNodo != null)
                    return RetNodo;
            }
            return null;
        }
    }
}








35.Aplicaciones web.SQL Parte 3.Curso de C# con Visual Studio 2017.

35- . Aplicaciones web. SQL Parte 3

   - 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'


34.Aplicaciones web.MasterPage.Curso de C# con Visual Studio 2017.

34- . Aplicaciones web.MasterPage

   - En este capítulo del curso de programación en c# con visual studio 2017 vamos 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.

- Video con el ejemplo:


 

-Información complemetaria:

https://msdn.microsoft.com/es-es/library/ehszf8ax(v=vs.100).aspx

- Os dejo el código del ejemplo de la página maestra:

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Master.master.cs" Inherits="GestionVarios.Master" %>

<!DOCTYPE html>

<html>
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
    <link href="estilos.css" rel="stylesheet" />
</head>
<body>
    <form id="form1" runat="server">
        <div class="estiloCentrado">
            <table width="1000" border="0" cellspacing="0" cellpadding="0">
                <tr>
                    <td width="1000" align="right" valign="middle" style="height: 40px;">
                        <img alt="" class="auto-style1" src="imagenes/cabecera.jpg" /></td>
                </tr>
            </table>
        </div>
        <div class="estiloCentrado">
            <a href="Default.aspx" class="linkbotonera">Inicio sesion</a>
            <a href="AltaUsuario.aspx" class="linkbotonera">Alta usuario</a>
            </div>
       <div class="estiloCentrado"     style="background-color:cornflowerblue">
       
                <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
                </asp:ContentPlaceHolder>
            </div>

            <div class="estiloCentrado">
                <table width="1012" border="0" cellspacing="0" cellpadding="0" style="margin-top: 10px;">
                    <tr>
                        <td align="center" valign="top" style="height: 35px;">
                              PIE DE PÁGINA
                        </td>
                    </tr>
                </table>
            </div>
    </form>
</body>
</html>

33.Aplicaciones web.Página de Login (2).Curso de C# con Visual Studio 2017.

33- . Aplicaciones web.Página de Login (2)

   - En este capítulo del curso de programación en c# con visual studio 2017 vamos a ver como crear un mecanismo 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:

  1. El usuario hace click en el enlace ¿Olvido su contraseña?
  2. Al hacer click solicitamos un email con el que validaremos que usuario existe en nuestro el sistema.
  3. 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.
  4. Esta url debería llegar al usuario via email.
  5. 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).
  6. Si todo es correcto apareceran en pantalla dos cajas de texto donde el usuario debe poner la nueva password.
  7. 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:

  • Default.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GestionVarios.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
           <asp:Label runat="server" ID="lblErrorREcordar"></asp:Label>
        <div id="divLogin" runat="server">
            <table width="200" border="0" cellspacing="0" cellpadding="0">
                <tr>
                    <td height="24">
                        <table width="200" border="0" cellspacing="0" cellpadding="0">
                            <tr>
                                <td width="75" align="right" valign="top">Usuario:&nbsp;&nbsp;&nbsp;&nbsp;
                                </td>
                                <td width="125">
                                    <asp:TextBox ID="txtUsuario" runat="server"></asp:TextBox>
                                    <asp:RegularExpressionValidator ID="mvalUsuarioValida" runat="server"
                                        ErrorMessage="Usuario incorrecto" ControlToValidate="txtUsuario"
                                        ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" Display="Dynamic" ForeColor="Red"></asp:RegularExpressionValidator>
                                    <asp:RequiredFieldValidator ID="mvalRequiereUsuario" runat="server" ErrorMessage="<br>Indique el usuario" ControlToValidate="txtUsuario" Display="Dynamic" ForeColor="Red"></asp:RequiredFieldValidator>
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
                <tr>
                    <td height="24">
                        <table width="200" border="0" cellspacing="0" cellpadding="0">
                            <tr>
                                <td width="75" align="right" valign="top" class="texto_news">Password:&nbsp;
                                </td>
                                <td width="125">
                                    <asp:TextBox ID="txtPassword" runat="server" TextMode="Password"></asp:TextBox>
                                    <asp:RegularExpressionValidator ID="mvalPasswordValida" runat="server" ErrorMessage="<br>Contraseña incorrecta" ControlToValidate="txtPassword" ValidationExpression="\w+.{5,}" Display="Dynamic" ForeColor="Red"></asp:RegularExpressionValidator>
                                    <asp:RequiredFieldValidator ID="mvalRequiereContraseña" runat="server" ErrorMessage="<br>Indique la contraseña" ControlToValidate="txtPassword" Display="Dynamic" ForeColor="Red"></asp:RequiredFieldValidator>
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
                <tr>
                    <td align="right" valign="middle">
                        <asp:Button runat="server" Text="Inicio sesion" OnClick="Unnamed1_Click" />
                        <br />
                        <asp:Label runat="server" ID="lblError"></asp:Label>
                    </td>
                </tr>

                <tr>
                    <td>
                        <table width="200" border="0" cellspacing="0" cellpadding="0">
                            <tr>
                                <td height="22" align="left"><a href="~/AltaUsuario.aspx" runat="server" target="_blank"><b>Darse de alta </b></a></td>
                            </tr>
                            <tr>
                                <td align="left">
                                    <asp:LinkButton ID="lnkOlvido" runat="server"
                                        CausesValidation="false" OnClick="lnkOlvido_Click"><b>¿Olvidó su password?</b></asp:LinkButton>
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        </div>
        <div id="divRecordar" runat="server" visible="false">
            <table id="mOlvidoPassword" width="400" border="0" cellpadding="0" cellspacing="0">
                <tr>
                    <td>
                        <br />
                        Si ha olvidado su pass, indíquenos el email con el que se registró:
                    </td>
                </tr>
                <tr>
                    <td width="200" align="left" class="texto_news">
                        <br />
                        Email<br />
                        <asp:TextBox ID="txtRecuperacion" runat="server"  Width="200px"></asp:TextBox>

                    </td>
                </tr>
                <tr>
                    <td align="right" valign="middle" height="30px">
                        <asp:Button runat="server" ID="btnRecordar" Text="Recordar pass" OnClick="btnRecordar_Click" />
                           <br />
                    
                    </td>
                </tr>
            </table>
        </div>
    </form>
</body>
</html>

  •  Default.aspx.cs:
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)
        {

        }

        protected void Unnamed1_Click(object sender, EventArgs e)
        {
           
            SqlConnection conexion = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
            string usuarioGuardadaBaseDatos  = String.Empty;
            byte[] passGuardadaBaseDatos = null;
            try
            {
                conexion.Open();
                SqlCommand com = conexion.CreateCommand();
                com.CommandType = System.Data.CommandType.StoredProcedure;
                com.CommandText = "dbo.ValidarUsuario";
               com.Parameters.Add("@email", SqlDbType.VarChar, 255).Value = txtUsuario.Text;

                SqlDataReader reader = com.ExecuteReader();

                if (reader.Read())
                {
                    usuarioGuardadaBaseDatos = reader["email"].ToString();
                    if(usuarioGuardadaBaseDatos!=String.Empty)
                    passGuardadaBaseDatos = (byte[])reader["pass"];
                  
                }
                else
                    throw new Exception("Usuario o pass incorrecto.");

                if(usuarioGuardadaBaseDatos!=String.Empty && ValidarDatos(usuarioGuardadaBaseDatos, passGuardadaBaseDatos))
                {
                    Response.Redirect("~/Pedidos.aspx");
                    Response.End();
               }
                else
                    throw new Exception("Usuario o pass incorrecto.");

            }
            catch (Exception ex)
            {
                lblError.Text = "Se produjo un error iniciando sesion:" + ex.Message;
                lblError.ForeColor = Color.Red;
             
            }
            finally
            {
                if (conexion != null && conexion.State == System.Data.ConnectionState.Open)
                    conexion.Close();

                conexion.Dispose();
            }

          
        }

        private Boolean ValidarDatos(string usuario, byte[] pass)
        {
            Boolean usuarioCorrecto = false;
            string passDescifrada = String.Empty;

            String miclave = ConfigurationManager.AppSettings["clave"];
            byte[] claveCifrado = System.Text.Encoding.ASCII.GetBytes(miclave);
            Cifrado c = new Cifrado(claveCifrado);
            passDescifrada = c.descifrar(pass);

      
            if (passDescifrada == txtPassword.Text && txtUsuario.Text == usuario)
                usuarioCorrecto = true;

            return usuarioCorrecto;
        }

        protected void lnkOlvido_Click(object sender, EventArgs e)
        {
            divRecordar.Visible = true;
            divLogin.Visible = false;
        }

        protected void btnRecordar_Click(object sender, EventArgs e)
        {
            SqlConnection conexion = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
           try
            {
                conexion.Open();
                SqlCommand com = conexion.CreateCommand();
                com.CommandType = System.Data.CommandType.StoredProcedure;
                com.CommandText = "dbo.ValidarUsuario";
                com.Parameters.Add("@email", SqlDbType.VarChar, 255).Value = txtRecuperacion.Text;

                SqlDataReader reader = com.ExecuteReader();

                if (reader.Read())
                {
                
                    EnviarDatos(txtRecuperacion.Text);

                }
                else
                    throw new Exception("Email no registrado en el sistema");

            }
            catch (Exception ex)
            {
                lblErrorREcordar.Text = "Se produjo un error recuperando password:" + ex.Message;
                lblErrorREcordar.ForeColor = Color.Red;

            }
            finally
            {
                if (conexion != null && conexion.State == System.Data.ConnectionState.Open)
                    conexion.Close();

                conexion.Dispose();
            }


        }

        protected void EnviarDatos(string Email)
        {
            try
            {
                string url = "https:";
                DateTime fecha = DateTime.Now;
                String miclave = ConfigurationManager.AppSettings["clave"];
                byte[] claveCifrado = System.Text.Encoding.ASCII.GetBytes(miclave);
                Cifrado c = new Cifrado(claveCifrado);
                byte[] emailCif= c.cifrar(Email);
                string encoded = HttpUtility.UrlEncode(Convert.ToBase64String(emailCif));

                // 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 ;

            }

            catch (Exception ex)
            {

                lblErrorREcordar.Text = "Se produjo un error recuperando password:" + ex.Message;
                lblErrorREcordar.ForeColor = Color.Red;
            }
        }
    }

      
}

  • RecuperarPass.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="RecuperarPass.aspx.cs" Inherits="GestionVarios.RecuperarPass" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Label ID="Label1" runat="server" Text="Nueva pass"></asp:Label>
            <asp:TextBox ID="txtPass1" runat="server" TextMode="Password"></asp:TextBox>
            <asp:RegularExpressionValidator ID="mvalPasswordValida" runat="server" ErrorMessage="<br>Contraseña incorrecta" ControlToValidate="txtPass1" ValidationExpression="\w+.{5,}" Display="Dynamic" ForeColor="Red"></asp:RegularExpressionValidator>
            <asp:RequiredFieldValidator ID="mvalRequiereContraseña" runat="server" ErrorMessage="<br>Indique la contraseña" ControlToValidate="txtPass1" Display="Dynamic" ForeColor="Red"></asp:RequiredFieldValidator>
            <br />
            <asp:Label ID="Label2" runat="server" Text="Confirmar pass" TextMode="Password"></asp:Label>
            <asp:TextBox ID="txtpass2" runat="server" TextMode="Password"></asp:TextBox>
            <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ErrorMessage="<br>Contraseña incorrecta" ControlToValidate="txtpass2" ValidationExpression="\w+.{5,}" Display="Dynamic" ForeColor="Red"></asp:RegularExpressionValidator>
            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="<br>Indique la contraseña" ControlToValidate="txtpass2" Display="Dynamic" ForeColor="Red"></asp:RequiredFieldValidator>
             <asp:CompareValidator ID="mcomPasswords" runat="server" ErrorMessage="Las contraseñas no son iguales." Display="Dynamic" ControlToCompare="txtPass1" ControlToValidate="txtpass2" ForeColor="Red"></asp:CompareValidator>
            <br />
            <asp:Button ID="Button1" runat="server" Text="Cambiar pass" OnClick="Button1_Click" />
            <asp:Label runat="server" ID="lblMensaje"></asp:Label>
        </div>
    </form>
</body>
</html>

  • RecuperarPass.aspx.cs:
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;
        }

        private void validarEmail(string email)
        {
            SqlConnection conexion = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
            try
            {
                conexion.Open();
                SqlCommand com = conexion.CreateCommand();
                com.CommandType = System.Data.CommandType.StoredProcedure;
                com.CommandText = "dbo.ValidarUsuario";
                com.Parameters.Add("@email", SqlDbType.VarChar, 255).Value = email;

                SqlDataReader reader = com.ExecuteReader();
               
                if (!reader.Read())
                        throw new Exception("Email no registrado en el sistema");

               

            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
                Response.End();

            }
            finally
            {
                if (conexion != null && conexion.State == System.Data.ConnectionState.Open)
                    conexion.Close();

                conexion.Dispose();
            }
        }
        private byte[] cifrar(string cadenaAcifrar)
        {
            String miclave = ConfigurationManager.AppSettings["clave"];
            byte[] claveCifrado = System.Text.Encoding.ASCII.GetBytes(miclave);
            Cifrado c = new Cifrado(claveCifrado);
            byte[] b = c.cifrar(cadenaAcifrar);
            return b;
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            SqlConnection conexion = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
            try
            {
                conexion.Open();
                SqlCommand com = conexion.CreateCommand();
                com.CommandType = System.Data.CommandType.StoredProcedure;
                com.CommandText = "dbo.ModificarPass";
                com.Parameters.Add("@email", SqlDbType.VarChar, 255).Value = obtenerMail();
                com.Parameters.Add("@pass", SqlDbType.VarBinary, 8000).Value = cifrar(txtPass1.Text);
                com.ExecuteNonQuery();

                lblMensaje.Text = "Password cambiada";
                lblMensaje.ForeColor = Color.Green;
            }
            catch (Exception ex)
            {
                lblMensaje.Text= ex.Message;
             

            }
            finally
            {
                if (conexion != null && conexion.State == System.Data.ConnectionState.Open)
                    conexion.Close();

                conexion.Dispose();
            }
        }
   
    }
}

  • Cifrado.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Web;

namespace GestionVarios
{
    public class Cifrado
    {
        Aes miAes = null;

        public Cifrado(byte[] clave)
        {
            miAes = Aes.Create();
            miAes.Key = clave;
            miAes.IV = clave;
        }

        public byte[] cifrar(string original)
        {
            byte[] encrypted = EncriptarStringToBytesAes(original, miAes.Key, miAes.IV);
            return encrypted;
        }

        public string descifrar(byte[] encrypted)
        {
            string roundtrip = DesencriptarStringFromBytesAes(encrypted, miAes.Key, miAes.IV);
            return roundtrip;

        }

        private byte[] EncriptarStringToBytesAes(string cadena, byte[] clave, byte[] IV)
        {

            if (cadena == null || cadena.Length <= 0)
                throw new ArgumentNullException("plainText");

            if (clave == null || clave.Length <= 0)
                throw new ArgumentNullException("Key");

            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");

            byte[] encrypted;

           using (Aes aesAlg = Aes.Create())
           {
                aesAlg.Key = clave;
                aesAlg.IV = IV;
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                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 (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = clave;
                aesAlg.IV = IV;

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
             
                using (MemoryStream msDecrypt = new MemoryStream(textoCifrado))
                {

                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                          plaintext = srDecrypt.ReadToEnd();

                        }
                    }

                }
            }
            return plaintext;
        }

    }
}

Curso .NET Core en C# - 34.Creamos nuestro propio log

34.Creamos nuestro propio log Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de  ASP.NET...