domingo, 19 de enero de 2020

ASP.NET Core - CRUD en MVC con C# - Parte 3

Continuamos con el desarrollo del CRUD en MVC con C# haciendo uso de ASP.NET Core, en la tercera parte implementaremos la funcionalidad de crear, listar, actualizar y eliminar registro de la tabla usuario creado en la base de datos BD_SEGURIDAD.

Se mantienen los mismo requisitos expuestos en las anteriores partes (puedes revisar):

Crear la funcionalidad de Crear un registro:
Cree el directorio Controllers en la raíz de la aplicación. Es esta carpeta agregue un nuevo controlador (Controlador de MVC: en blanco) llamado HomeController.cs

El controlador tendrá el siguiente código inicial como se muestra a continuación:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace DEMO01_CRUD.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

Cambie el código del controlador de inicio como se muestra a continuación con la finalidad de poder acceder al archivo de configuración para la conexión con la base de datos:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace DEMO01_CRUD.Controllers
{
    public class HomeController : Controller
    {
       public IConfiguration Configuration { get; }
       public HomeController(IConfiguration configuration) {
            Configuration = configuration;
        }

public IActionResult Index()
        {
            return View();
        }
    }
}

Recuerde que la cadena de conexión se mantiene en el archivo appsettings.json. 

Para acceder a este archivo (appsettings.json.), se debe obtener el objeto de la interfaz IConfiguration a través de la función Inyección de dependencias. Por lo tanto, se agrega la interfaz IConfiguration en el constructor de HomeController y el patrón del MVC que nos proporcionará automáticamente el objeto.

Ahora crearemos la funcionalidad crear o agregar Usuario, para esto se realizará a través de un nuevo método de acción llamado CREATE. Por lo tanto, agregue los métodos de  la acción Create al Home Controller como se muestra a continuación:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Threading.Tasks;
using DEMO01_CRUD.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;

namespace DEMO01_CRUD.Controllers
{
    public class HomeController : Controller
    {
       public IConfiguration Configuration { get; }
       public HomeController(IConfiguration configuration) {
            Configuration = configuration;
        }

public IActionResult Index()
        {
            return View();
        }

       public IActionResult Create() {
            return View();
        }

        [HttpPost]
        public IActionResult Create(ClsUsuario clsUsuario)
        {
            if (ModelState.IsValid) {
                string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
                using (SqlConnection connection = new SqlConnection(connectionString)) {
                    string sql = $"Insert Into USUARIO(Usuario, Contrasena, Intentos, NivelSeg) Values('{clsUsuario.usuario}', '{clsUsuario.contrasena}', '{clsUsuario.intentos}', '{clsUsuario.nivelSeg}')";

                    using (SqlCommand command = new SqlCommand(sql, connection))
                    {
                        command.CommandType = CommandType.Text;

                        connection.Open();
                        command.ExecuteNonQuery();
                        connection.Close();
                    }
                    return RedirectToAction("Index");
                }
            }
            else
            return View();
        }
    }
}

Para lograr la conexión con la tabla usuario, en el método create obtuvo la cadena de conexión en la siguiente línea:
string connectionString = Configuration["ConnectionStrings:DefaultConnection"];

Luego hacemos uso del objeto SqlCommand para insertar los registros del usuario ejecutando la consulta SQL Insertar:

string sql = $"Insert Into USUARIO(Usuario, Contrasena, Intentos, NivelSeg) Values('{clsUsuario.usuario}', '{clsUsuario.contrasena}', '{clsUsuario.intentos}', '{clsUsuario.nivelSeg}')"

Dentro de esta carpeta Views, cree una nueva carpeta llamada Home. A continuación, cree una nuevo view llamada Create.cshtml dentro de esta carpeta Home (es decir, Views/Home) y agregue el siguiente código a esta Vista:

@model DEMO01_CRUD.Models.ClsUsuario

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    var title = "CREAR USUARIO";
    ViewData["Title"] = title;
}

<style>

    .input-validation-error {
        border-color: red;
    }
</style>
<div class="row justify-content-center">
    <h4>@title</h4>
</div>

<hr />
<div class="row">
    <div class="col-md-12">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="usuario" class="control-label"></label>
                <input asp-for="usuario" class="form-control" />
                <span asp-validation-for="usuario" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="contrasena" class="control-label"></label>
                <input asp-for="contrasena" class="form-control" />
                <span asp-validation-for="contrasena" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="intentos" class="control-label"></label>
                <input asp-for="intentos" class="form-control" />
                <span asp-validation-for="intentos" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="nivelSeg" class="control-label"></label>
                <input asp-for="nivelSeg" class="form-control" />
                <span asp-validation-for="nivelSeg" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-success" /> |
                <a asp-action="Index" class="btn btn-info">Volver a la lista</a>
            </div>
        </form>
    </div>
</div>

<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>

Al hacer clic en el botón Enviar, se llama a la acción Create del tipo HttpPost y se crean los nuevos registros del usuario.

Observe los 3 archivos de script que realizan la Validación del lado del cliente de los campos de entrada en la Vista:

<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>

Ahora esta listo para validar funcionalidad de crear o agregar usuario.

Ejecute la aplicación y en el navegador vaya a la URL de la vista Create, que es - http://localhost:2551/Home/Create. Verá el formulario CREAR USUARIO en el navegador.

Al carga el http://localhost:2551/Home/Create

Sin completar ningún campo, presione el botón Create y verá los errores de validación que muestran los complementos de validación de jQuery.

Esto se logra haciendo uso de la librería jQuery Validation
Ahora complete todos los campos (como se muestra en la imagen a continuación) y haga clic en el botón Create.

Ingresa los datos a registrar
El registro del usuarios se creará en la base de datos y nos redirigirá a la Vista de Index que actualmente está vacía.

Puede validar que el registro se agregó en la tabla del usuario. Para ello, vaya al "Explorador de objetos de SQL Server", luego haga clic derecho en la tabla usuario y seleccione Ver datos.

La tabla usuario se abrirá y verás el nuevo registro, vea la imagen a continuación:


Crear la funcionalidad de Listar (leer) un registro:
Ahora crearemos la Funcionalidad Lista (leer) usuario. Por lo tanto, cambie el código de la Acción de Index en el Home Controller para que todos los registros se muestren en la Vista:

Cambie el código como se muestra a continuación:

        public IActionResult Index()
        {
            List<ClsUsuario> UsuariosList = new List<ClsUsuario>();

            string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
            using (SqlConnection connection = new SqlConnection(connectionString)) {

                connection.Open();

                string sql = "select * from USUARIO";
                SqlCommand command = new SqlCommand(sql, connection);

                using (SqlDataReader dataReader = command.ExecuteReader())
                {
                    while (dataReader.Read())
                    {
                        ClsUsuario clsUsuario = new ClsUsuario();
                        clsUsuario.id = Convert.ToInt32(dataReader["Id"]);
                        clsUsuario.usuario = Convert.ToString(dataReader["Usuario"]);
                        clsUsuario.contrasena = Convert.ToString(dataReader["Contrasena"]);
                        clsUsuario.intentos = Convert.ToInt32(dataReader["Intentos"]);
                        clsUsuario.nivelSeg = Convert.ToDecimal(dataReader["NivelSeg"]);
                        clsUsuario.fechaReg = Convert.ToDateTime(dataReader["FechaReg"]);

                        UsuariosList.Add(clsUsuario);
                    }
                }

                connection.Close();
            }
            return View(UsuariosList);
}

En esta acción se ejecuta la consulta "select * from USUARIO" con el método ExecuteReader() de SqlCommand para obtener un objeto SqlDataReader.

Luego recorremos todos los registros con el método Read() de SqlDataReader y creo un objeto de lista de todos los registros que contiene la tabla usuario. Este objeto se devuelve a la Vista como Modelo al final del código.

Ahora agregue la vista Index dentro de la carpeta Views/Home con el siguiente código:

@model IEnumerable<DEMO01_CRUD.Models.ClsUsuario>

@{
    var title = "LISTAR USUARIO";
    ViewData["Title"] = title;
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="row justify-content-center">
    <h4>@title</h4>
</div>
<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.id)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.usuario)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.contrasena)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.intentos)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.nivelSeg)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.fechaReg)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.id)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.usuario)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.contrasena)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.intentos)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.nivelSeg)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.fechaReg)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.id }) |
                @Html.ActionLink("Details", "Details", new { id = item.id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.id })
            </td>
        </tr>
}
    </tbody>
</table>

Considera que también he creado las columnas para la funcionalidad Actualizar y Eliminar en los elementos thead y tbody de la tabla:

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.id)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.usuario)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.contrasena)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.intentos)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.nivelSeg)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.fechaReg)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.id)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.usuario)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.contrasena)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.intentos)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.nivelSeg)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.fechaReg)
            </td>
            <td>
                @Html.ActionLink("Edit""Edit"new { id = item.id }) |
                @Html.ActionLink("Details""Details"new { id = item.id }) |
                @Html.ActionLink("Delete""Delete"new { id = item.id })
            </td>
        </tr>
}
    </tbody>
</table>

Prueba de la funcionalidad de listar (lectura), ejecute la aplicación y verá que los registros de la tabla usuario se muestran en la Vista Index. Se muestra en la imagen a continuación:


Crear la funcionalidad de Actualizar (editar) un registro:
Agrega los métodos de la Acción de Actualización (editar) al Home Controller. El código a considerar para agregar al controlador se muestra a continuación:

        public IActionResult Edit(int id)
        {
            string connectionString = Configuration["ConnectionStrings:DefaultConnection"];

            ClsUsuario clsUsuario = new ClsUsuario();
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                string sql = $"Select * From USUARIO Where Id='{id}'";
                SqlCommand command = new SqlCommand(sql, connection);

                connection.Open();

                using (SqlDataReader dataReader = command.ExecuteReader())
                {
                    while (dataReader.Read())
                    {
                        clsUsuario.id = Convert.ToInt32(dataReader["Id"]);
                        clsUsuario.usuario = Convert.ToString(dataReader["Usuario"]);
                        clsUsuario.contrasena = Convert.ToString(dataReader["Contrasena"]);
                        clsUsuario.intentos = Convert.ToInt32(dataReader["Intentos"]);
                        clsUsuario.nivelSeg = Convert.ToDecimal(dataReader["NivelSeg"]);
                        clsUsuario.fechaReg = Convert.ToDateTime(dataReader["FechaReg"]);

                    }
                }
                connection.Close();
            }
            return View(clsUsuario);
        }

        [HttpPost]
        [ActionName("Edit")]
        public IActionResult Edit_Post(ClsUsuario clsUsuario)
        {
            string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
            using (SqlConnection connection = new SqlConnection(connectionString))
            {            
                string sql = $"Update USUARIO SET Usuario='{clsUsuario.usuario}', Contrasena='{clsUsuario.contrasena}', Intentos='{clsUsuario.intentos}', NivelSeg='{clsUsuario.nivelSeg}' Where Id='{clsUsuario.id}'";
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    connection.Open();
                    command.ExecuteNonQuery();
                    connection.Close();
                }
            }

            return RedirectToAction("Index");
        }

La versión HttpGet del método de acción Editar toma el "id" del registro en su parámetro y luego ejecuta la consulta SQL llamada $"Select * From USUARIO Where Id='{id}'" con el objeto SqlCommand. Obtiene el valor del registro del usuario y lo devuelve a la Vista de actualización (Editar).

La versión HttpPost del método Edit de la Acción realiza la actualización real del registro del usuario mediante el objeto ADO.NET "SqlCommand". Lo importante a tener en cuenta es la consulta de actualización que es:

string sql = $"Update USUARIO SET Usuario='{clsUsuario.usuario}', Contrasena='{clsUsuario.contrasena}', Intentos='{clsUsuario.intentos}', NivelSeg='{clsUsuario.nivelSeg}' Where Id='{clsUsuario.id}'";

A continuación, cree la Vista de actualización (editar) dentro de la carpeta Views/Home con el siguiente código:

@model DEMO01_CRUD.Models.ClsUsuario

@{
    var title = "ACTUALIZAR USUARIO";
    ViewData["Title"] = title;
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<style>

    .input-validation-error {
        border-color: red;
    }
</style>

<div class="row justify-content-center">
    <h4>@title</h4>
</div>
<hr />
<div class="row">
    <div class="col-md-12">
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="id" class="control-label"></label>
                <input asp-for="id" class="form-control" disabled />
                <span asp-validation-for="id" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="usuario" class="control-label"></label>
                <input asp-for="usuario" class="form-control" />
                <span asp-validation-for="usuario" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="contrasena" class="control-label"></label>
                <input asp-for="contrasena" class="form-control" />
                <span asp-validation-for="contrasena" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="intentos" class="control-label"></label>
                <input asp-for="intentos" class="form-control" />
                <span asp-validation-for="intentos" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="nivelSeg" class="control-label"></label>
                <input asp-for="nivelSeg" class="form-control" />
                <span asp-validation-for="nivelSeg" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="fechaReg" class="control-label"></label>
                <input asp-for="fechaReg" class="form-control" disabled />
                <span asp-validation-for="fechaReg" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-success" /> |
                <a asp-action="Index" class="btn btn-info">Volver a la lista</a>
            </div>
        </form>
    </div>
</div>

<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>

La vista es similar a la vista de Index que creamos anteriormente; el campo "Id" es de solo lectura para que el usuario no pueda cambiarlo.

Validar la funcionalidad de Actualizar (edit) usuario. Ejecute la aplicación y haga clic en el enlace Edit para los registros del primer registro, vea la imagen a continuación:



El registro se abrirá para la actualización. Cambie el nombre a CESAR y el nivel de seguridad a 5. Finalmente, haga clic en el botón Save como se muestra en la imagen a continuación:



El registro se actualizará y se redirigirá a la Vista de Index donde puede ver los campos de registro actualizados como se muestra en la imagen a continuación:

Usuario y nivel de seguridad actualizado
Crear la funcionalidad de Eliminar un registro:
Cree el método Eliminar acción en Home Controller cuyo código se proporciona a continuación:

[HttpGet]//Lo uso para ver el detalle del registro y para la eliminacion de registro
        public IActionResult Delete(int? id)
        {
            string connectionString = Configuration["ConnectionStrings:DefaultConnection"];

            ClsUsuario clsUsuario = new ClsUsuario();
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                string sql = $"Select * From USUARIO Where Id='{id}'";
                SqlCommand command = new SqlCommand(sql, connection);

                connection.Open();

                using (SqlDataReader dataReader = command.ExecuteReader())
                {
                    while (dataReader.Read())
                    {
                        clsUsuario.id = Convert.ToInt32(dataReader["Id"]);
                        clsUsuario.usuario = Convert.ToString(dataReader["Usuario"]);
                        clsUsuario.contrasena = Convert.ToString(dataReader["Contrasena"]);
                        clsUsuario.intentos = Convert.ToInt32(dataReader["Intentos"]);
                        clsUsuario.nivelSeg = Convert.ToDecimal(dataReader["NivelSeg"]);
                        clsUsuario.fechaReg = Convert.ToDateTime(dataReader["FechaReg"]);
                    }
                }
            }
            return View(clsUsuario);
        }

        //[HttpPost]//Se puede usar directo, invocando desde el view Index a través de un boton con HttpPost
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public IActionResult DeleteConfirmed(int? id)
        {
            string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                string sql = $"Delete From USUARIO Where Id='{id}'";
                using (SqlCommand command = new SqlCommand(sql, connection))
                {
                    connection.Open();
                    try
                    {
                        command.ExecuteNonQuery();
                    }
                    catch (SqlException ex)
                    {
                        ViewBag.Result = "Error en la operación:" + ex.Message;
                    }
                    connection.Close();
                }
            }

            return RedirectToAction("Index");
        }

Este método toma la identificación del registro del usuario en su parámetro y luego ejecuta la consulta Eliminar SQL:

string sql = $"Delete From USUARIO Where Id='{id}'";

Probar la funcionalidad de Eliminar usuario, ejecute la aplicación y haga clic en el enlace "Delete" que aparece en cualquiera de los registros. 

Clic en Delete
Ahora confirma la eliminación haciendo clic en el botón Delete.

Verifique las siguientes imágenes que muestran el proceso de eliminación de registros:
El registro fue eliminado

Agrear la funcionalidad de ver detalle:
Para esto crea el método de acción  Details en Home Controller cuyo código se proporciona a continuación:

        [HttpGet]
        public IActionResult Details(int? id)
        {
            string connectionString = Configuration["ConnectionStrings:DefaultConnection"];

            ClsUsuario clsUsuario = new ClsUsuario();
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                string sql = $"Select * From USUARIO Where Id='{id}'";
                SqlCommand command = new SqlCommand(sql, connection);

                connection.Open();

                using (SqlDataReader dataReader = command.ExecuteReader())
                {
                    while (dataReader.Read())
                    {
                        clsUsuario.id = Convert.ToInt32(dataReader["Id"]);
                        clsUsuario.usuario = Convert.ToString(dataReader["Usuario"]);
                        clsUsuario.contrasena = Convert.ToString(dataReader["Contrasena"]);
                        clsUsuario.intentos = Convert.ToInt32(dataReader["Intentos"]);
                        clsUsuario.nivelSeg = Convert.ToDecimal(dataReader["NivelSeg"]);
                        clsUsuario.fechaReg = Convert.ToDateTime(dataReader["FechaReg"]);
                    }
                }
            }
            return View(clsUsuario);
  }

Este método toma la identificación del registro del usuario según su parámetro y luego ejecuta la consulta Eliminar SQL:

string sql = $"Select * From USUARIO Where Id='{id}'";

Valida la funcionalidad de ver Details del usuario seleccionado:

Clic en Details para poder veer el detalla de dicho registro

Para ir finalizando se visualiza todo el detalla del registro seleccionado, además nos permitirá ir a la opción de actualizar registro haciendo clic en edit.
Clic en Edit si desea actualizar
En esta tercera parte usted aprendió acerca de como:
Crear la funcionalidad de Crear un registro.
Crear la funcionalidad de Listar (leer) un registro.
Crear la funcionalidad de Actualizar un registro.
Crear la funcionalidad de Eliminar un registro.

Agradecer de antemano por la revisión y lectura de este apartado que fue desarrollado y publicado con la intención de incrementar el nivel de conocimiento en el mundo del desarrollo de software.

Puedes descargar la fuentes desde:
 Descargar fuente de ASP.NET-Core-CRUD-MVC

0 comentarios :