Aplicación web con ASP.NET MVC 2 – parte 9

En esta parte de nuestro tutorial, implementaremos la administración de grupos para nuestros cuatrimestres en un nuevo controlador llamado AdministrarGrupos, en esta parte haremos uso de JQuery para visualizar nuestros registros de grupos por cuatrimestres y programa educativo, posteriormente implementaremos también la gestión de alumnos.

Img. 1. Resultado de nuestro avance al finalizar esta parte.

El nuevo controlador AdministrarGrupos.

Agregue el nuevo controlador AdministrarGrupos, cuya acción Index puede recibir un parámetro que será el Id del cuatrimestre del cual se quieren visualizar sus grupos, sin recibir parámetro mostrará solo la vista vacía (sin ninguna lista),  pero ademas debe mostrar controles para alternar la información que queremos visualizar; algo similar ya se ha hecho en la acción Index de AdministrarTutores (revise esa parte para entender de que se trata y como funciona).

Img. 2. Agregar nuevo controlador AdministrarGrupos.

El código de nuestro controlador empezará con nuestra acción Index (Requiere de más trabajo, debe analizar el código fuente para entender su funcionamiento):

public class AdministrarGruposController : Controller
{
    BDEscolarEntities BD = new BDEscolarEntities();
    //
    // GET: /AdministrarGrupos/
    public ActionResult Index(int idcuatrimestre=0)
    {
        //Crear la lista de programas educativos para mostrarlos en la vista Index
        var programaseducativos = BD.ProgramaEducativo.ToList();
        programaseducativos.Insert(0, new ProgramaEducativo { IdPE = 0, NombreCorto = "" });

        //Pasar la lista de PE´s a la vista
        ViewData["ProgramasEducativos"] = programaseducativos;

        //Crear parámetros auxiliares para
        //Id del programa educativo (si se está recibiendo el id de cuatrimestre)
        //Id del cuatrimestre (si se está recibiendo el id de cuatrimestre)
        //Nombre del PE (si se está pasando el id de cuatrimestre)
        //Periodo del cuatrimestre
        ViewData["IdPE"] = "";
        ViewData["IdCuatrimestre"] = "";
        ViewData["ProgramaEducativo"] = "";
        ViewData["Cuatrimestre"] = " - ";
        //si no se está especificando el cuatrimestre
        //crear una lista vacia de la clase Grupo
        if (idcuatrimestre == 0)
        {
            //Crear la lista vacía porque no se mostrar grupos de algún cuatrimestre
            List<Grupo> grupos = new List<Grupo>();

            //pasar la lista vacía a la vista
            return View(grupos);
        }
        else //Si se especifica el cuatrimestre, cargar sus grupos
        {
            //Buscar el cuatrimestre indicado
            //como restricción, debe ser del año actual
            var cuatrimestre = BD.Cuatrimestre.Where(c => c.Id == idcuatrimestre && c.Anio == DateTime.Now.Year).FirstOrDefault();
            if (cuatrimestre != null)
            {
                //Pasar los datos reales
                ViewData["IdPE"] = cuatrimestre.IdPE;
                ViewData["ProgramaEducativo"] = cuatrimestre.ProgramaEducativo.NombreCorto.Trim();
                ViewData["IdCuatrimestre"] = cuatrimestre.Id;
                ViewData["Cuatrimestre"] = cuatrimestre.PeriodoInicio.Trim() + " - " + cuatrimestre.PeriodoFin.Trim();

                //Pasar la lista de cuatrimestres al que corresponde el indicado
                //utilizando nuestra clase auxiliar
                List<AuxCuatrimestre> cuatrimestres = new List<AuxCuatrimestre>();

                //Recorrer la lista de cuatrimestres (ordenados a-z) del PE
                foreach(Cuatrimestre item in cuatrimestre.ProgramaEducativo.Cuatrimestre.Where(c => c.IdPE == cuatrimestre.IdPE && c.Anio== DateTime.Now.Year).OrderBy(c => c.PeriodoInicio))
                    cuatrimestres.Add( new AuxCuatrimestre { Id = item.Id, Periodo = item.PeriodoInicio.Trim() + " - " + item.PeriodoFin.Trim(), Anio = item.Anio}); 

                //Ahora si pasamos nuestra lista de cuatrimestres
                ViewData["cuatrimestres"] = cuatrimestres;

                //Y el dato principal es la lista de grupos del cuatrimestre seleccionado
                return View(cuatrimestre.Grupo.ToList());
            }
            else
                return View("Error");
        }
    }

}

La vista Index.

Crear la vista tipada para la clase Grupo con contenido List.

Img. 3. Crear vista Index.

El código de nuestra vista Index, empieza como a continuación se muestra, posteriormente se le irán haciendo modificaciones donde se les mostrarán las lineas de código como guías para saber donde hacer los cambios.

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Administrar grupos
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Administrar grupos</h2>
    Filtrar por Programa Educativo: <%: Html.DropDownList("IdPE", new SelectList(ViewData["ProgramasEducativos"] as IEnumerable, "IdPE", "NombreCorto", ViewData["IdPE"]))%>
    Cuatrimestre: 

    <% // si se tiene la lista de cuatrimestres, crear el combo con sus opciones, sino, crear uno vacío %>
    <% if (ViewData["cuatrimestres"] != null)
       { %>
         <%: Html.DropDownList("IdCuatrimestre", new SelectList(ViewData["cuatrimestres"] as IEnumerable, "Id", "Periodo", ViewData["IdCuatrimestre"]))%>
       <%}
       else
       { %>
         <select id="IdCuatrimestre" name="IdCuatrimestre"></select>
    <% } %>
    <br /><br />

    <strong>Programa Educativo</strong>: <span id="nombrepe"><%: ViewData["ProgramaEducativo"] %></span>,
    <strong>Cuatrimestre</strong>: <span id="nombrecuatrimestre"><%: ViewData["Cuatrimestre"] %></span>.<br /><br />

    <% // asignamos un ID para nuestra tabla de grupos
       // porque la manipularemos con JQuery %>

    <table id="GruposTbl">
    <% //Cambia de TR a THEAD la fila del encabezado de la tabla %>
        <thead>
            <th></th>
            <th>
                Id Grupo
            </th>
            <th>
                Nombre
            </th>
            <th>
                Cuatrimestre
            </th>
            <th>
                Tutor
            </th>
        </thead>
        <% //Agrega la etiqueta TBODY a la tabla
            //Lo utilizaremos para manipular su contenido %>
        <tbody>
    <% foreach (var item in Model) { %>

        <tr>
            <td>
                <%: Html.ActionLink("Editar", "Editar", new { id=item.IdGrupo }) %> |
                <%: Html.ActionLink("Eliminar", "Eliminar", new { id=item.IdGrupo })%>
            </td>
            <td>
                <%: item.IdGrupo %>
            </td>
            <td>
                <%: item.Nombre %>
            </td>
            <td>
            <% //Cambia el IdCuatrimestre por el periodo del cuatrimestre %>
                <%: item.Cuatrimestre.PeriodoInicio + " " + item.Cuatrimestre.PeriodoFin %>
            </td>
            <td>
            <% //Cambia el IdTutor por el nombre completo del tutor %>
                <%: item.Tutor.Nombre + " " + item.Tutor.Apellidos%>
            </td>
        </tr>

    <% } %>
    </tbody>
    </table>

    <p id="LinkAltaGrupo">
        <%: Html.ActionLink("Create New", "Create") %>
    </p>

</asp:Content>

Comprobando la funcionalidad:

Al ejecutar nuestra aplicación y al ingresar a http://localhost:XXXX/AdministrarGrupos nos mostrará nuestra vista como se ve en la imagen.

Img. 4. Vista sin especificar el Id del cuatrimestre.

Observe que no se está pasando el Id del cuatrimestre del cual se quieren ver sus grupos, razón por la cual la lista aparece vacía (pero tampoco se han creado grupos :D), Aparece la lista de PE, y el combo de cuatrimestres aparece vacío, cuando el usuario seleccione un PE, se llenará automáticamente el combo de cuatrimestres.

Ahora ingresemos a la vista pero especificando el parámetro idcuatrimestre cuyo valor sea un Id de cuatrimestre válido, cheque sus PE´s registrados y vea los ID de alguno de sus cuatrimestres, en mi caso mis ID de cuatrimestres válidos (año 2011) son los ID 9 y 10, así que probaré con uno de ellos.

Img. 5. Vista que recibe el id del cuatrimestre.

Hasta aquí va funcionando correctamente, pero hace falta algo muy importante, el registro de nuevos grupos.

Lo que haremos será, si se ha especificado un Id de cuatrimestre para ver sus grupos, mostraremos el link Registrar grupo, por ahora el link lo tenemos como “Create New“.

Así que en la vista Index, reemplace la linea de código (dentro del párrafo con id=”LinkAltaGrupo”):

<%: Html.ActionLink(“Create New”, “Create”) %>

por:

        <% if (ViewData["IdCuatrimestre"] != "")
           { %>

            <%: Html.ActionLink("Registrar nuevo grupo", "Registrar", new { id = ViewData["IdCuatrimestre"] })%>

       <%  } %>

Ahora verifique que al ingresar en http://localhost:XXXX/AdministrarGrupos no muestre el link, y al especificar el id de cuatrimestre si muestre el link, ej. http://localhost:XXXX/AdministrarGrupos?idcuatrimestre=9.

Registrar Grupos.

Crearemos la acción Registrar y su vista en la cual el usuario solo tenga que seleccionar los valores (nombre o letra del grupo y Tutor).

La acción Registrar.

public ActionResult Registrar(int id)
{
    //Verificar que el cuatrimestre para el que se ha de registrar el grupo existe

    var cuatrimestre = BD.Cuatrimestre.Where(c => c.Id == id).FirstOrDefault();
    if (cuatrimestre != null)
    {
        //crear un nuevo objeto de la clase Grupo y definir sus datos que tendrá por defecto
        Grupo nuevogrupo = new Grupo();

        //asociar el objeto cuatrimestre al grupo
        nuevogrupo.Cuatrimestre = cuatrimestre;

        List<AuxTutor> tutores = new List<AuxTutor>(); //crear una lista con la nueva clase auxiliar

        //transformar nuestra lista de tutores a nuestra nueva lista de la clase AuxTutor
        //En esta clase solo asignamos el ID y el nombre completo del tutor
        foreach (Tutor tutor in BD.Tutor.Where(t => t.IdPE == cuatrimestre.IdPE))
            tutores.Add(new AuxTutor { Id = tutor.IdTutor, Nombre = tutor.Nombre.Trim() + " " + tutor.Apellidos.Trim() });

        //Pasar a la vista la lista de tutores del PE al que pertenece el cuatrimestre
        ViewData["Tutores"] = tutores;

        //pasar nuestro objeto a la vista
        return View(nuevogrupo);
    }else
       return View("Error");
}

Observe que en esta acción estamos utilizando otra nueva clase llama AuxTutor en la cual solo le implementamos 2 propiedades, para ello, en la carpeta Models, agregue esta clase:

namespace EscuelaWebApp.Models
{
    public class AuxTutor
    {
        private int id;
        private string nombre;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        public string Nombre
        {
            get { return nombre; }
            set { nombre = value; }
        }

   }
}

Crear la vista Registrar:

Img. 6. Crear la vista Registrar.

En esta vista utilizaremos una nueva vista parcial (plantilla) para no trabajar doble en las vistas Registrar y Editar, el código de nuestra vista Registrar quedará así:

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Registrar grupo
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Registrar grupo</h2>

    <% using (Html.BeginForm()) {%>
        <%: Html.ValidationSummary(true) %>

        <fieldset>
            <legend>Datos del grupo</legend>
            <p><%:ViewData["Mensaje"] %></p>
            <%: Html.EditorFor(model => Model, ViewData["Tutores"] = ViewData["Tutores"]) %>

            <p>
                <input type="submit" value="Registrar grupo" />
            </p>
        </fieldset>

    <% } %>

    <div>
        <%: Html.ActionLink("Regresar a la lista de grupos", "Index", new { idcuatrimestre = Model.Cuatrimestre.Id }, null)%>
    </div>

</asp:Content>

Crear nuestra vista parcial llamada Grupo.ascx

En la carpeta Views/AdministrarGrupos agregue su carpeta EditorTemplates, de la misma forma como se explicó en la parte 8 cuando empezamos a trabajar con la validación de formularios.

Ahora a EditorTemplates agregue una nueva vista parcial llamada Grupo:

Img. 7. Crear vista parcial Grupo.

El código para nuestra vista parcial quedará como este:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<EscuelaWebApp.Models.Grupo>" %>

<div class="editor-label">
    Programa educativo
</div>
<div class="editor-field">
    <% // crear un cuadro de texto donde se muestre el nombre del programa educativo como solo lectura %>
        <input type="text" value="<%: Model.Cuatrimestre.ProgramaEducativo.NombreCorto %>" readonly="readonly" />
</div>

<div class="editor-label">
    Cuatrimestre
</div>
<div class="editor-field">
    <% // crear nuestro campo IdCuatrimestre
        // como input Hiden que porte el Id del cuatrimestre (no se puede modificar)
        // y aparte un cuadro de texto donde se muestre el periodo del cuatrimestre como solo lectura %>
        <%: Html.HiddenFor(model => model.IdCuatrimestre)%>
        <input type="text" value="<%: Model.Cuatrimestre.PeriodoInicio + " - " + Model.Cuatrimestre.PeriodoFin %>" readonly="readonly" />
</div>

<div class="editor-label">
    Nombre del grupo
</div>
<div class="editor-field">
    <% //: Html.TextBoxFor(model => model.Nombre) %>
    <% // Crear un combo para seleccionar la letra del grupo  %>
    <select id="Nombre" name="Nombre">
        <option value="A">A</option>
        <option value="B">B</option>
        <option value="C">C</option>
        <option value="D">D</option>
        <option value="E">E</option>
        <option value="F">F</option>
    </select>
    <%: Html.ValidationMessageFor(model => model.Nombre) %>
</div>            

<div class="editor-label">
    Tutor
</div>
<div class="editor-field">
    <% //: Html.TextBoxFor(model => model.IdTutor) %>
    <%: Html.DropDownList("IdTutor", new SelectList(ViewData["Tutores"] as IEnumerable, "Id", "Nombre"))%>
    <%: Html.ValidationMessageFor(model => model.IdTutor) %>
</div>

Puede implementar un mecanismo para gestionar las letras para asignar como nombre del grupo, de forma que pudiera comprobar cuales nombres ya existen y no mostrarlos a usuario para que no pueda seleccionarlo como opción.

Ahora comprobemos la funcionalidad, para ello ingrese a ver los grupos de un cuatrimestre, ej. http://localhost:XXXX/AdministrarGrupos?idcuatrimestre=9:

Vemos que tenemos nuestro link para agregar un nuevo grupo a este cuatrimestre.

Img. 8. Ir a registrar nuevo grupo.

Ahora al hacer clic sobre “Registrar nuevo grupo“, tenemos nuestro resultado:

Img. 9. Vista registrar grupo.

Falta crear nuestra acción Registrar que reciba los datos del formulario y los guarde en la BD.

La acción [HttpPost] Registrar queda como:

[HttpPost]
public ActionResult Registrar(Grupo grupo)
{
    //primero comprobaremos que el nombre del grupo no exista
    //para el cuatrimestre seleccionado.
    var comprobargrupo = BD.Grupo.Where(g => g.Nombre.Trim() == grupo.Nombre && g.IdCuatrimestre == grupo.IdCuatrimestre).FirstOrDefault();
    //si el grupo NO existe, agregarlo a la BD.
    if (comprobargrupo == null)
    {
        BD.AddToGrupo(grupo);
        BD.SaveChanges();

        //Redireccionar a los grupos del cuatrimestre para el que se creó el grupo
        return Redirect("..\\Index?idcuatrimestre="+grupo.IdCuatrimestre);
    }
    else //Si ya existe el grupo, informarlo a usuario
    {
        //volver a recuperar el cuatrimestre para obtener todos sus datos
        var cuatrimestre = BD.Cuatrimestre.Where(c => c.Id == grupo.IdCuatrimestre).FirstOrDefault();
        if (cuatrimestre != null)
            grupo.Cuatrimestre = cuatrimestre; //reasigar el objeto cuatrimestre al grupo

        //ViewData["Mensaje"] es recibido por la vista Registrar.
        ViewData["Mensaje"] = "No se puede registrar el grupo ("+grupo.Nombre +") porque ya existe, elija otra letra a asignar.";

        //Volver a crear nuestra lista tutores
        List<AuxTutor> tutores = new List<AuxTutor>();
        //transformar nuestra lista de tutores a nuestra nueva clase
        foreach (Tutor tutor in BD.Tutor.Where(t => t.IdPE == grupo.Cuatrimestre.ProgramaEducativo.IdPE))
            tutores.Add(new AuxTutor { Id = tutor.IdTutor, Nombre = tutor.Nombre.Trim() + " " + tutor.Apellidos.Trim() });

        //Pasar a la vista la lista de tutores del PE al que pertenece el cuatrimestre
        ViewData["Tutores"] = tutores;

        //Regresamos nuevamente el objeto grupo a la vista para su modificación
        return View(grupo);
    }

Ahora ejecutando nuestra aplicación al registrar nuestro nuevo grupo, tenemos nuestra acción HttpPost Registrar funcionando.

Img. 10. Grupo registrado.

Ahora al intentar registrar nuevamente un grupo con la letra o nombre “A“, nos devuelve la vista con los datos del grupo pero NO registrado.

Img. 11. Intentando registrar el mismo grupo.

Notese que para la clase Grupo no es están validando los datos (no se hace validación de formulario), lo que se hace es que antes de registrar el grupo se verifica que no exista un grupo con el mismo nombre o letra para el cuatrimestre seleccionado, si ya existe, pasamos un mensaje de error a la vista, pero no esta de más que por su cuenta implemente la validación para esta clase y haga que los combos aparezcan vacíos para que el usuario elija una opción.

Por su cuenta implemente la acciones Editar y Eliminar, solo considere que para eliminar un grupo debe comprobar que no tenga asignado ningún alumno.

Esta parte del tutorial queda hasta aquí para no hacerlo más largo, en la siguiente parte agregaremos la funcionalidad a los combos Programa educativo y Cuatrimestre para hacer las consultas AJAX y JSON para cambiar el contenido de nuestra tabla de grupos, de esa forma el usuario no tendrá que regresar a PE´s y seleccionar cuatrimestre para administrar sus grupos.

11 comentarios en “Aplicación web con ASP.NET MVC 2 – parte 9

  1. Hola! Interesante… Ya hice una aplicacion en MVC2 pero quiero ejecutarlo en un servidor IIS… Podrias subir un tutorial o un link para realizar la ejecucion… POr favor.!!! Gracias! 🙂

    1. Hola, yo publique mi proyecto en un servidor remoto donde se encuentra la base de datos y me anda perfecto, lo que hice es, click derecho en el proyecto y seleccionar Publish, eliges el metodo de publicar, en tu caso File System, local IIS

      con eso creo q deberia andar, si es en un servidor, verifica que tenga instalado el framework 4.

      sino es muy tarde, espero q te sirva de ayuda.

  2. no te preocupes man si pude realizarlo..igual muchas gracias excelente ejemplo muy completo me esta sirviendo muchisimo 😀 😀

  3. hola amigazo si podrian compartir la parte en la cual se …considere que para eliminar un grupo debe comprobar que no tenga asignado ningún alumno.

    lo implemente y me sale error de datos vacios …cuando doy eliminar y deberia salir la vista ErrorEliminarGrupo –> “este registro si tiene alumnos y nose puede eliminar” ….o si quiere se elimine en cascada osea todo en donde tenga relacion

    me sale ese error ojala me puedas ayudar gracias storm_sh4dow@hotmail.com
    espero tu respuesta 😀

    1. Por ahora no dispongo de tiempo suficiente para hacer eso; el ejemplo es muy básico, donde la BD no contempla restricciones pero puedes agregarselas, para lo que quieres pues agrega OnDelete en la tabla grupo-alumno = Restrict, al intentar ejecutar la consulta que elimine el grupo te generará un excepción que debes controlar; por otra parte, puedes hacer un conteo de los alumno asociados, si el conteo es 0, entonces eliminar, si no, pues no eliminar (regla del negocio).
      PD: Lo que tu quieres va más por el tema sobre BD y la integridad referencial.

    1. El obetivo de este tutorial no esta en pasar el código fuente, ya que el tutorial está basado en el ejemplo tal y como se va realizando, los avances que voy realizando voy transcribiendolo al tutorial, de hecho, el tutorial lo estoy publicando para los alumnos con los que estamos trabajando con asp.net mvc 2, y hasta el momento ellos han implementado todas las partes y obtenido los resultados que aquí se muestran y hecho los complementos que se mencionan.

      1. Hola profe como ha estado espero que bien!!!
        Este comentario es pra ver si puede subir o crear sus demos pero que se pueda visualizar su trabajo realizado….
        Saludos (Chino —>(Utim))

  4. Hola, felipe esta muy bueno los post, me parese muy bien que te tomes tu tiempo para publicar nuevos post y asi compartir tus experiencias, yo quisiera hacerte de manera de sugerencia pienso que realizarias un ejemplo mas completo, como una matricula de alumnos a los cursos, haciendo uso de todo lo que publicastes anteriormente,otra cosita tu estas trabajando con entity framework mira como lo trabajaria si utilizo oracle??? creo que seria bueno el ejemplo que le realices algo estandar para oracle,mysql y sql, etc. , yo se que a la mayoria que revisa tu post lo serviria mucho para poder aprender mvc2

    1. Si leíste la parte uno del tutorial eso es a lo que vamos a llegar pero todo por partes, al final deben tenerse listas de grupos y generar los pdf´s de los grupos, aparte utilizar entity framework con otros gestores de datos es lo mismo que con Sql Server, solo tienes que agregar tu conexión hacia tu servidor, visita el sitio de mysql y busca sobre entity framework en mysql, este documento está completo y explicado http://dev.mysql.com/doc/refman/5.1/en/connector-net-tutorials-entity-framework-winform-data-source.html y este es otro http://www.oracle.com/webfolder/technetwork/tutorials/obe/db/dotnet/EntityFrameworkOBE/EntityFrameworkOBE.htm , puedes también trabajar con algún framework MVC en PHP y Java.

Escribe tu comentario:

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s