Además, haremos uso de la base de datos de Microsoft SQL Server 2017 para la creación del procedimiento almacenado (implementación - Transact-SQL); mencionar que hará uso de la tabla Usuario creado en el proyecto ASP.NET Core - Implementando CRUD en MVC con C#.
Requisitos:
- Microsoft Visual Studio Community 2019
- Microsoft .NET Core, ASP.NET Core 3.1
- Microsoft SQL Server 2017 (RTM-GDR) - Express Edition (64-bit)
- Framework Bootstrap (para mejorar el diseño de nuestra aplicación)
- Framework jQuery Validation (para la validación de lado del cliente)
Lo que veremos en este articulo:
Paso 1: Crear el procedimiento almacenado - Transact-SQL.
CREATE PROCEDURE [dbo].[GET_SEG_USUARIO]
@usuario VARCHAR (50),
@contrasena VARCHAR (250)
AS
BEGIN
SELECT usuario, contrasena
FROM Usuario
WHERE usuario = @usuario AND contrasena = @contrasena
END
El procedimiento almacenado cuenta con 2 parámetros (@us8uario y @contrasena) de entrada con el fin de retornar el usuario y contraseña de acuerdo a los datos ingresado desde la aplicación que se restringe desde el Script de Transact-SQL con la sentencia básica del Where (WHERE usuario = @usuario AND contrasena = @contrasena).
Paso 2: Implementar cadena de conexión a la base de datos.
![]() |
Clic en Agregar |
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=HPAREDES\\SQLEXPRESS;Database=BD_SEGURIDAD;UID=usuario_para_acceder_al_server;Password=contraseña_para_acceder_al_server"
}
}
Paso 3: Agregar los paquetes de dependencia desde NuGet.
Microsoft.Data.SqlClient es la creación de un nuevo SqlClient, es un nuevo espacio de nombre que permite la convivencia del antiguo System.Data.SqlClient.
Paso 4: Implementar el método de validación.
using
Microsoft.AspNetCore.Mvc.ModelBinding.Validation;//Iniciamos el namespace ModelBinding Validation
namespace DEMO03_LOGIN.CustomValidation
{
public class ContrasenaValidate : Attribute,
IModelValidator//Acceder a la interfaz
IModelValidator
{
public string ErrorMessage {
get; set; }
/// <summary>
/// Función para la retornar validación - función con inyección de dependencia
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public
IEnumerable<ModelValidationResult> Validate(ModelValidationContext
context)
{
return new
List<ModelValidationResult>
{
new ModelValidationResult("",
ErrorMessage)
};
}
}
}
Paso 5: Crear la entidad usuario y agregar atributos.
public class ClsUsuario
{
public int id { get; set; }
[Required]
public string usuario { get; set; }
[Required]
[ContrasenaValidate(ErrorMessage = "Contraseña no valida")]
public string contrasena { get; set; }
public int intentos { get; set; }
public decimal nivelSeg { get; set; }
public DateTime?
fechaReg { get; set; }
}
Descripción de cada atributos:
Paso 6: Modificar la Configuración del Startup.
using
Microsoft.AspNetCore.Builder;
using
Microsoft.Extensions.DependencyInjection;
namespace DEMO03_LOGIN
{
public class Startup
{
public void
ConfigureServices(IServiceCollection services)
{
services.AddMvc(option => option.EnableEndpointRouting = false);
services.AddSession();
}
public void
Configure(IApplicationBuilder app)
{
app.UseSession();
app.UseMvc(router =>
{
router.MapRoute(
name: "default",
template: "{controller=Login}/{action=Login}/{id?}");
});
}
}
Paso 7: Agregar el controlador e implementar los ActionResults.
using
System.Collections.Generic;//Lista
de colecciones genericas
using
System.Data;//Identificar
el tipo de objeto a manipular en base de datos
using
Microsoft.Data.SqlClient;//Controlador
de acceso a datos
using System.Linq;//Para hacer macth entre lista del dataReader y los antributos del modelo (usuario y contrasena)
using
DEMO03_LOGIN.Models;//Para
instanciar los atributos de la entidad usuario
using
Microsoft.Extensions.Configuration;//Para acceder al archivo de configuración appsettings.json
using Microsoft.AspNetCore.Http;//Para el manejo de solicitudes y
respuestas HTTP
/// <summary>
/// Constante para Inicializar la Sesión _User
/// </summary>
const string SessionUser = "_User";
public IConfiguration
Configuration { get; }
/// <summary>
/// Interfaz para acceder a los valores del archivo de configuración
/// </summary>
/// <param name="configuration"></param>
public LoginController(IConfiguration configuration)
{
Configuration =
configuration;
}
/// <summary>
/// Action para inicializar la carga de la vista del Login en base a los
atributos de modelo usuario
/// </summary>
/// <returns></returns>
public ActionResult
Login()
{
//ViewBag.ReturnUrl = returnUrl;
return View(new ClsUsuario());
}
/// <summary>
/// Action de tipo POST para para
inicializar el proceso de validación e iniciar sesión en base a los datos del modelo
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost]
//[ValidateAntiForgeryToken]
public ActionResult
Login(ClsUsuario model)
{
//Conexión a la base de datos
string
connectionString = Configuration["ConnectionStrings:DefaultConnection"];
//Estoy usando uso de ADO.Net para
interactuar con la base de datos
using (SqlConnection
connection = new SqlConnection(connectionString))
{
var list_users = new
List<ClsUsuario>();
//@1Inicio: Validar los controladores
if (model.usuario == null || model.usuario.Equals("") ||
model.contrasena == null || model.contrasena.Equals(""))
{
ModelState.AddModelError("", "Ingresar los datos solictiados");
}//@1Final
else
{
connection.Open();//Abrir la
conexión a la base de datos
SqlCommand com = new SqlCommand("GET_SEG_USUARIO", connection);//Referencia al
procedimiento almacenado
com.CommandType =
CommandType.StoredProcedure;//Se
define el tipo de comando a utilizar
//Paso los parámetros de acuerdo
a los datos cargados segun el modelo usario
com.Parameters.AddWithValue("@usuario",
model.usuario);
com.Parameters.AddWithValue("@contrasena", model.contrasena);
SqlDataReader dr = com.ExecuteReader();//Ejecuto el comando a través de un DataReader
//@2Inicio: Recorro los datos y
adiciono en la lista list_users los valores usuario y contrasena
while (dr.Read())
{
ClsUsuario clsUsuario = new ClsUsuario();
clsUsuario.usuario = Convert.ToString(dr["Usuario"]);
clsUsuario.contrasena = Convert.ToString(dr["Contrasena"]);
list_users.Add(clsUsuario);//Adicionar en la lista
}
//@2Final
//@3Inicio: Match entre los
valores ingresados y la lista
if (list_users.Any(p => p.usuario == model.usuario &&
p.contrasena == model.contrasena))
{
HttpContext.Session.SetString(SessionUser,
model.usuario);//Iniciamos
la sesión pasando el valor (nombre del usuario)
return RedirectToAction("Usuario", "Home");//Redireccionar a la vista usario (Lista
de Usuarios)
}
else
{
ModelState.AddModelError("", "Datos ingresado no válido.");//Error
personalizado
}
}
return View(model);
}
}
/// <summary>
/// Action para limpiar y cerrar la sesión de la aplicación
/// </summary>
/// <returns></returns>
[HttpPost]
//[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
HttpContext.Session.Clear();//Limpiar la sesión
return RedirectToAction("Login", "Login");//Redireccionar a la vista login
}
Paso 8: Agregar la vista Login e implementar el cshtml.
<!--@@1 Inicio: Importamos el modelo usuario y
definimos un titulo-->
@model DEMO03_LOGIN.Models.ClsUsuario
@{
var title = "Acceso
al Sistema";
ViewData["Title"] = title;
Layout = null;
}
<!--@@1 Final-->
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@title</title>
<!--@@2 Inicio: Importamos la
librería js jQuery, el css bootstrap y asimismo posicionamos el
formulario-->
<link href="/lib/bootstrap-4.3.1/dist/css/bootstrap.css" rel="stylesheet" />
<script src="/lib/jquery/dist/jquery.min.js"></script>
<style><
.form-signin {
margin: 0 auto;
max-width: 330px;
padding: 15px;
}
.form-signin h4 {
text-align: center;
}
</style>
<!--@@2 Final-->
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<h3>LOGIN MVC ASP.Net Core 3.1</h3><!--Definimos una cabecera en la página-->
</div>
</div>
<div class="container body-content">
<!--@@3 Inicio: Método de tipo post
para validar o iniciar el acceso a la aplicación-->
@using
(Html.BeginForm("Login", "Login", FormMethod.Post, new { @class = "form-signin", role = "form" }))
{
@Html.AntiForgeryToken()
<h4>@title</h4>
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.TextBoxFor(m =>
m.usuario, new { @class = "form-control", placeholder = "Usuario" })
@Html.ValidationMessageFor(m
=> m.usuario, "", new { @class = "text-danger" })
<br />
@Html.PasswordFor(m =>
m.contrasena, new { @class = "form-control", placeholder = "Contraseña" })
@Html.ValidationMessageFor(m => m.contrasena, "", new { @class = "text-danger" })
<br />8
<input type="submit" value="Iniciar sesión" class="btn btn-lg btn-primary btn-block" />
}
<!--@@3 Final-->
</div>
</body>
</html>
Paso 9: Modificar la vista _Layout.cshtml.
<!--@@1 Inicio: Importamos el name para la
comnicación http y capturamos el valor de sesión-->
@using Microsoft.AspNetCore.Http
@{
var vUser = Context.Session.GetString("_User");<!--Capturar la sesión en la
variable vUser-->
}
<!--@@1 Final-->
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewData["Title"]</title><!--Capturamos el titulo
definido en el vista que corresponda (en este caso sera de la vista Index -
LISTAR USUARIO)-->
<!--@@2 Inicio: Importamos la
librería js jQuery y el css bootstrap-->
<link href="/lib/bootstrap-4.3.1/dist/css/bootstrap.css" rel="stylesheet" />
<script src="/lib/jquery/dist/jquery.min.js"></script>
<!--@@2 Final-->
</head>
<body>
<div class="container">
<div class="row justify-content-lg-center">
<div class="row">
<div class="col-12 badge-info">
<h3>LOGIN MVC ASP.Net Core 3.1</h3><!--Cabera de la página-->
</div>
</div>
</div>
<div class="row justify-content-lg-end">
<div class="row">
<!--@@3 Inicio: Pasar el valor de
la variable vUser (sessión) a al parráfo; además invocamos al Action LogOff
para cerrar la sesión-->
<div class="col">
<p>USUARIO: @vUser</p><!--valor de la sesión-->
</div>
<div class="col">
@using (Html.BeginForm("LogOff", "Login", FormMethod.Post, new { id = "logoutForm", @class
= "form-css" }))
{
<a href="javascript:document.getElementById('logoutForm').submit()"><i class="fa fa-fw
fa-power-off"></i> Cerrar Sesión</a>
}
</div>
<!--@@3 Final-->
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer class="row justify-content-center">
<p>
© 2017 - @DateTime.Now.Year
<a href="http://www.hadsonpar.com/" target="_blank">HadsonPar</a> |
My LOGIN
Application MVC ASP.Net Core 3.1
</p>
</footer>
</div>
</body>
</html>
Paso 10: Pantalla del demo desarrollado.
![]() |
El segundo mensaje de "Contraseña no valida" es un tipo de mensaje personalizado haciendo uso de un función de inyección de dependencia (mayor detalle en el paso4). |
![]() |
Ingresar los datos correctos y acceder a la aplicación. |
![]() |
En la vista index se muestra la lista de Usuario y la opción Cerrar Sesión se encuentra en la vista compartido _Layout.cshtml . |
3 Comentarios
Gracias por el excelente artículo en .NET core, si alguien quiere consultarlo en .NET MVC revise aquí
ResponderBorrarLogin and register in ASP.NET MVC
Hola Miguel, gracias por el comentarios y aporte. Saludos.
BorrarHola, gracias por el comentario - déjame revisar el demo y te comento como me va. Saludos.
ResponderBorrar