INTRODUCCIÓN:
Hola, bienvenido al último capítulo del tutorial “Login Completo” en C#, Visual Basic, SQL Server, WinForms, Programación Orientada a Objetos (POO) y Arquitectura en Capas, con buenas prácticas y estrategias (Nivel intermedio).
En este tutorial aprenderá: Como permitir al usuario, pueda editar su perfil y cambiar de contraseña, evitar insertar datos duplicados, agregar seguridad al momento de editar los datos.
PRE-TUTORIAL:
Base de Datos
En el capítulo 2, se creó la base de datos mi compañía, una tabla usuarios, algunos campos. Para este tutorial, editaremos estos campos.
create database MyCompany use MyCompany create table Users( UserID int identity(1,1) primary key, LoginName nvarchar (100) unique not null, Password nvarchar (100) not null, FirstName nvarchar(100) not null, LastName nvarchar(100) not null, Position nvarchar (100) not null, Email nvarchar(150)not null )
IMPORTANTE:
El campo LoginName es único (Unique), por lo tanto no se podrá registrar nombres de usuario duplicados. De hacerlo, como resultado se tendrá un error, ese error será capturado desde la capa de dominio.
TUTORIAL:
Paso 1: Codificar- Capa de Acceso a Datos
- En el objeto de acceso a datos del Usuario (UserDao), agregamos un nuevo método para editar los campos de la tabla Usuarios.
UserDao.cs / .vb
public void editProfile(int id,string userName, string password, string name, string lastName, string mail) { using (var connection = GetConnection()) { connection.Open(); using (var command = new SqlCommand()) { command.Connection = connection; command.CommandText = "update Users set LoginName=@userName, Password=@pass, FirstName=@name, LastName=@lastName, Email=@mail where UserID=@id"; command.Parameters.AddWithValue("@userName", userName); command.Parameters.AddWithValue("@pass", password); command.Parameters.AddWithValue("@name", name); command.Parameters.AddWithValue("@lastName", lastName); command.Parameters.AddWithValue("@mail", mail); command.Parameters.AddWithValue("@id", id); command.CommandType = CommandType.Text; command.ExecuteNonQuery(); } } }
Imports System.Data.SqlClient Imports Common Public Class UserDao Inherits ConnectionToSql Public Sub editProfile(id, user, pass, name, lastName, mail) Using connection = GetConnection() connection.Open() Using command = New SqlCommand() command.Connection = connection command.CommandText = "update Users set LoginName=@user, Password=@pass, FirstName=@name, LastName=@lastName, Email=@mail where UserID=@id" command.Parameters.AddWithValue("@user", user) command.Parameters.AddWithValue("@pass", pass) command.Parameters.AddWithValue("@name", name) command.Parameters.AddWithValue("@lastName", lastName) command.Parameters.AddWithValue("@mail", mail) command.Parameters.AddWithValue("@id", id) command.CommandType = CommandType.Text command.ExecuteNonQuery() End Using End Using End Sub End Class
Ya comenté en algunos videos la importancia de usar USING, La declaración using garantiza que se llame a Dispose una vez termine de ejecutarse los códigos dentro del bloque using, incluso si ocurre una excepción. Para entender mejor, una vez que termine de ejecutarse el método requestUserPassword, se desechará los objetos sqlConnection y sqlCommand, es por ello que no es necesario, cerrar la conexión o limpiar los parámetros de sqlCommand.
Importante….Tener muy en cuenta
Paso 2: Codificar- Capa de Dominio / Negocio
- En la clase modelo de usuario (UserModel.vb), creamos los atributos del usuario y el constructor con parámetros para inicializar los atributos, también creamos un constructor sin parámetros (Es necesario, porque se invoco desde muchos formularios mediante constructor sin parámetros-> dim userModel as new UserModel()), también puedes inicializar los atributos por propiedades (get – set), es decision tuya.
- Creamos un método para editar el perfil de usuario e invocar el método editar perfil de la capa de acceso a datos.
UserModel.cs / .vb
UserDao userDao = new UserDao(); //Attributes private int idUser; private string loginName; private string password; private string firstName; private string lastName; private string position; private string email; //Constructors public UserModel(int idUser, string loginName, string password, string firstName, string lastName, string position, string email) { this.idUser = idUser; this.loginName = loginName; this.password = password; this.firstName = firstName; this.lastName = lastName; this.position = position; this.email = email; } public UserModel() { } //Methods public string editUserProfile() { try { userDao.editProfile(idUser, loginName, password, firstName, lastName, email); LoginUser(loginName, password); return "Your profile has been successfully updated"; } catch (Exception ex) { return "Username is already registered, try another"; } }
Imports DataAccess Imports Common Public Class UserModel Dim userDao As New UserDao() 'Attributes' Private idUser Private loginName Private password Private firstName Private lastName Private position Private email 'Constructors' Public Sub New(idUser As Object, loginName As Object, password As Object, firstName As Object, lastName As Object, position As Object, email As Object) Me.idUser = idUser Me.loginName = loginName Me.password = password Me.firstName = firstName Me.lastName = lastName Me.position = position Me.email = email End Sub Public Sub New() End Sub 'Methods' Public Function editUserProfile() As String Try userDao.editProfile(idUser, loginName, password, firstName, lastName, email) Login(loginName, password)'Invocamos el metodo login para actualizar los datos del usuario en la interfaz gráfica' Return "Your profile has been successfully updated" Catch ex As Exception Return "Username is already registered, try another" End Try End Function Public Function Login(user As String, pass As String) As Boolean Return userDao.Login(user, pass) End Function
Paso Final: Codificar- Capa de Presentación
- Agregamos un nuevo formulario para mostrar y editar los datos del usuario, de la siguiente manera.
FormUserProfile.cs / vb [Diseño]
La propiedad VISIBLE del panel de edición debe estar establecida en FALSO, para mantenerlo oculta al ejecutar la aplicación y solamente mostrarlo cuando el usuario decida editar sus datos.
- Una vez diseñado el formulario, codificamos de la siguiente manera:
FormUserProfile.cs / .vb [Código]
private void FormUserProfile_Load(object sender, EventArgs e) { loadUserData(); initializePassEditControls(); } private void loadUserData() { //View lblUser.Text = UserCache.LoginName; lblName.Text = UserCache.FirstName; lblLastName.Text = UserCache.LastName; lblMail.Text = UserCache.Email; lblPosition.Text = UserCache.Position; //Edit Panel txtUsername.Text = UserCache.LoginName; txtFirstName.Text = UserCache.FirstName; txtLastName.Text = UserCache.LastName; txtEmail.Text = UserCache.Email; txtPassword.Text = UserCache.Password; txtConfirmPass.Text = UserCache.Password; txtCurrentPassword.Text = ""; } private void initializePassEditControls() { LinkEditPass.Text = "Edit"; txtPassword.UseSystemPasswordChar = true; txtPassword.Enabled = false; txtConfirmPass.UseSystemPasswordChar = true; txtConfirmPass.Enabled = false; } private void reset() { loadUserData(); initializePassEditControls(); } private void linkEdit_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { Panel1.Visible = true; loadUserData(); } private void LinkEditPass_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { if (LinkEditPass.Text == "Edit") { LinkEditPass.Text = "Cancel"; txtPassword.Enabled = true; txtPassword.Text = ""; txtConfirmPass.Enabled = true; txtConfirmPass.Text = ""; } else if (LinkEditPass.Text == "Cancel") { initializePassEditControls(); txtPassword.Text = UserCache.Password; txtConfirmPass.Text = UserCache.Password; } } private void btnSave_Click(object sender, EventArgs e) { if (txtPassword.Text.Length >= 5) { if (txtPassword.Text == txtConfirmPass.Text) { if (txtCurrentPassword.Text == UserCache.Password) { var userModel = new UserModel( idUser: UserCache.IdUser, loginName: txtUsername.Text, password: txtPassword.Text, firstName: txtFirstName.Text, lastName: txtLastName.Text, position: null, email: txtEmail.Text); var result = userModel.editUserProfile(); MessageBox.Show(result); reset(); Panel1.Visible = false; } else MessageBox.Show("Icorrect current password, try again"); } else MessageBox.Show("The password do not match, try again"); } else MessageBox.Show("The password must have a minimum of 5 characters"); }
Imports Common Imports Domain Public Class FormEditUserProfile Private Sub FormEditUserProfile_Load(sender As Object, e As EventArgs) Handles MyBase.Load loadUserData() initializeControlsEditPass() End Sub Private Sub loadUserData() 'View lblUser.Text = ActiveUser.loginName lblName.Text = ActiveUser.firstName lblLastName.Text = ActiveUser.lastName lblMail.Text = ActiveUser.email lblPosition.Text = ActiveUser.position 'Edit txtUsername.Text = ActiveUser.loginName txtFirstName.Text = ActiveUser.firstName txtLastName.Text = ActiveUser.lastName txtEmail.Text = ActiveUser.email txtPassword.Text = ActiveUser.password txtConfirmPass.Text = ActiveUser.password End Sub Private Sub initializeControlsEditPass() LinkEditPass.Text = "Edit" txtPassword.UseSystemPasswordChar = True txtPassword.Enabled = False txtConfirmPass.UseSystemPasswordChar = True txtConfirmPass.Enabled = False txtCurrentPassword.Text = "" End Sub Private Sub reset() loadUserData() initializeControlsEditPass() End Sub Private Sub LinkEditPass_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LinkEditPass.LinkClicked If LinkEditPass.Text = "Edit" Then LinkEditPass.Text = "Cancel" txtPassword.Enabled = True txtPassword.Text = "" txtConfirmPass.Enabled = True txtConfirmPass.Text = "" ElseIf LinkEditPass.Text = "Cancel" Then initializeControlsEditPass() txtPassword.Text = ActiveUser.password txtConfirmPass.Text = ActiveUser.password End If End Sub Private Sub linkEdit_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles linkEdit.LinkClicked Panel1.Visible = True loadUserData() End Sub Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click If txtPassword.Text = txtConfirmPass.Text Then If txtCurrentPassword.Text = ActiveUser.password Then Dim userModel As New UserModel(idUser:=ActiveUser.idUser, loginName:=txtUsername.Text, password:=txtPassword.Text, firstName:=txtFirstName.Text, lastName:=txtLastName.Text, position:=Nothing, email:=txtEmail.Text) Dim result = userModel.editUserProfile() MessageBox.Show(result) reset() Panel1.Visible = False Else MessageBox.Show("Incorrect current password") End If Else MessageBox.Show("The passwords do not match, try again") End If End Sub Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click Panel1.Visible = False reset() End Sub End Class
- Finalmente invocamos el formulario perfil de usuario desde cualquier botón, label o linklabel en el menu principal.
Dim formUserProfile As New FormEditUserProfile() formUserProfile.Show()
Puede ver este tutorial en YouTube
C#
VB.Net
DESCARGAS:
Descargar Proyecto Login Completo + CRUD
La descarga del proyecto (No es gratis) incluye las funciones realizadas en los 6 capítulos del proyecto LOGIN COMPLETO EN C# o LOGIN COMPLETO EN VB.NET, sin embargo, el proyecto tiene un código fuente totalmente modernizado y optimizado, además de incluir CRUD completo con manejo de imágenes, validación de datos duplicados, entre otros. Todo ello con SQL Server, WinForm, Programación Orientada a Objetos (POO) y Arquitectura en Capas, con buenas prácticas y estrategias, tanto de nivel intermedio o avanzado. Puedes descargar las versiones de demostración y obtener los proyectos desde lo botones a continuación:
C# (C-Sharp)
VB.NET (Visual Basic)
Los comentarios están cerrados.