Nothing Special   »   [go: up one dir, main page]

Marco Teorico

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 11

MVC 5

Este tutorial está enfocado en la programación MVC y Entity Framework Code First
(Entidades creadas en la base de datos a través de código desde la aplicación).
Crear Aplicación CRUD (Create Read Update Delete) entidades básicas: Existen
varias formas de desarrollar este tipo de aplicaciones básicas, para agilizar el tiempo y
no agotarlo en módulos más complejos, como transacciones del sistema (factura, detalle
factura, etc.). Utilizaremos los asistentes que proporciona Microsoft para estos efectos,
sin dejar de analizar parte del código para futuras modificaciones.
1. Creación Entidades:
Considerando los conceptos de Ingeniería de Software – Modelando la Estructura del
Sistema (UML), donde la gráfica de diagrama de clases nos orienta sobre la solución y
cómo plasmarla a través de las clases (Entidades), comenzamos por crearla como parte del
modelo de datos.
Nota: Estás entidades pueden estar en otros proyectos anexos (ejemplo proyectos de capa
de negocio o capa de Entidades), sólo gráfico un ejemplo básico.

System.ComponentModel.DataAnnotations: Ofrece clases de atributos que se utilizan para


definir los metadatos para ASP.NET MVC y controles de datos ASP.NET. (Ejemplos KEY,
[StringLength(40, ErrorMessage = "Name cannot be longer than 40”]).
Esto nos permite darle definiciones a los atributos de nuestra clase, estos pueden ser:
[Key]: Indica que el atributo es Primary keys de la clase y de las posteriores tablas.
[StringLength(40)]: Indica el máximo de caracteres que puede tener un string.
[Range(300, 3000)][Range(typeof(DateTime), "1/2/2004", "3/4/2004",ErrorMessage = "Value
for {0} must be between {1} and {2}")]: Permite generar rangos en los datos para una
futura validación del modelo (Model.IsValid)
Uso de MetaData: Nos permite dejar libre de los atributos de la clase entity.
using System;
using System.Web.DynamicData;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;

[MetadataType(typeof(ProductMetaData))]
public partial class Product
{

}
public class ProductMetaData
{
// Personalizar la apariencia y el comportamiento de los campos de datos
// para tipos de datos no intrínsecos (tipo object) en el modelo de datos

[Range(10, 1000,
ErrorMessage = "Value for {0} must be between {1} and {2}.")]
public object Weight;

[Range(300, 3000)]
public object ListPrice;

[Range(typeof(DateTime), "1/2/2004", "3/4/2004",


ErrorMessage = "Value for {0} must be between {1} and {2}")]
public object SellEndDate;

2. Configuración WebConfig:
Es uno de los pilares del sistema, permite manejar el connectionString, el cual maneja las
conexiones con las bases de datos a través del Contexto.
<connectionStrings>
<add name="StoreContext"
connectionString="Data Source=.;Initial Catalog=Store;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>

3. Crear un controlador:
Para nuestro ejemplo y desarrollo a través de Asistentes, crearemos un controlador con la
opción:
Creará de forma automática las opciones CRUD e incluso la conexión dinámica de contexto
Entity framework Code First,

Clase de Modelo: Permite seleccionar la Clase Entidad creada en la capa de modelos, en


este caso Productos.

Clase de Contexto de Datos: Fundamental ya que será en nombre de la conexión de las


Entidades registradas en el Sistema.

Nombre Controlador: Se llamará igual al nombre de la Entidad para mantener su


descendencia, pero con la palabra Controller al final (ProductoController.cs).

Nota Importante: Este asistente creará un nuevo connectionString con el mismo nombre
pusimos al Clase de Contexto de Datos y debemos modificarlo para que apunte de forma
directa (ver Configuración WebConfig)

4.- Ejecución del Software: Se tardará un poco más de lo normal y creará la base de
datos con la tabla Product (ojo que si pones español la crea productoes) ya que
scaffolding (asistente de creación de tablas similar al de ruby and rails) sólo está
confeccionado para palabras en inglés.
5.- Seguridad integrada: Si te logueas a través de la página veras que creará tablas
adicionales con la configuración de IIS de forma automática.

Proyecto terminado y probado


https://www.youtube.com/watch?v=7lL8w-ZSWuU&list=PLuEZQoW9bRnQAVxaDusY0fjRb2u7wgpzI&index=7
Migraciones Automáticas:
Una de las debilidades de las aplicaciones EntityFramework eran las migraciones, eso
implicaba que si creábamos nuevos campo a la entidad se caía la aplicación y debíamos
borrar la base de datos, ejecutando la aplicación que generaba una nueva base vacía,
lo cual implicaba perdida de datos.
Para evitar eso se generó las migraciones automáticas las cuales pasaremos a definir y
explicar sus utilidades:
1- Paso es Digitar en la Consola Package Console el comando que habilita esta función.
Enable-Migrations –ContextTypeName Nombre_Contexto –EnableAutomaticMigrations
Nombre_Contexto: Nombre que puso asistente de contextos antes creado

Con la ejecución de este comando creó una carpeta en nuestro proyecto llamada
Migrations en donde nos crea una clase llamada Configuration.cs

2- Velar por los Datos, abrir el archivo Configuration.cs y digitar la siguiente


línea:

AutomaticMigrationDataLossAllowed = true;

3- Debemos configurar la aplicación que cada vez que inicie verifique si los modelos
sufrieron algún cambio. Esto de hace en el archivo Global.asax de la siguiente
manera. (poner cabecera System.Data.Entity)
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Models.NombreContexto, Migrations.Configuration>());
Crear Relaciones y DataAnnotations:
Las clases al igual que las tablas también tienen relaciones y se vinculan entre ellas,
además entregar atributos a las propiedades de cada clase:

Relación de Uno a Muchos:

Dos clases una clase llamada TipoDocumento y la otra Persona, un tipo documento puede tener muchas personas y una persona
sólo puede tener un tipo TipoDocumento.
public class TipoDocumento
{
[Key]
public int IdTipoDocumento{ get; set; }
public string DescTipoDocumento { get; set; }
Public Vitual ICollection<Persona> Personas { get; set; }
}
Donde Clase Persona es una Colección dentro de la clase TipoDocumento. Virtual: es un modificador de Acceso.
public class Persona
{
[Key]
public int IdPersona { get; set; }
public string Nombre { get; set; }
public string Paterno { get; set; }
public string Materno { get; set; }
public string Direccion { get; set; }
public DateTime FechaNacimiento { get; set; }
public DateTime HoraIngreso { get; set; }
public string EMail { get; set; }
public string URL { get; set; }
public int IdTipoDocumento { get; set; }
public virtual TipoDocumento TipoDocumento { get; set; }
}
Nótese que clase Persona maneja una relación con la clase TipoDocumento, además debe agregar el campo IdTipoDocumento para
manejar la relación de las clases.
Nota: Antes de crear el controlador debe compilar para que las clases generen las modificaciones de estructuras en la base de datos.
Creamos el controlador con la Opción
DataAnnotations:

Permite entregar atributos a las propiedades de las clases que posteriormente serán importadas a la base de datos:

[Display(Name ="Tipo Documento")]


Cambia el nombre del campo para aspectos del View
[Key]
Indica que el campo es Primary Key de la Clase
[Required(ErrorMessage ="Debe ingresar el {0}")]
Indica que el campo es Requerido y personaliza el mensaje de error {0} es un comodín que mostrará el nombre de la propiedad.
[StringLength(30, ErrorMessage = "El campo {0} debe tener de {1} y {2}", MinimumLength =3)]
Indica el máximo y mínimo de caracteres de debe tener el campo, {1} comodín para máximo {2} para mínimo.
[DisplayFormat(DataFormatString ="{0:C2}", ApplyFormatInEditMode = false)]
Define formato moneda con dos decimales
[DisplayFormat(DataFormatString ="{0:yyyy/MM/dd}", ApplyFormatInEditMode = false)]
Define formato fecha
[DisplayFormat(DataFormatString ="{0:hh:mm}", ApplyFormatInEditMode = true)]
Define formato Hora
[DataType(DataType.Date)]
Genera el formato en el View a través de JQuery de tipo fecha, un control con formato grafico en el textbox .(También Valida)
[DataType(DataType.Time)]
Genera el formato en el View a través de JQuery de tipo Hora, un control con formato grafico en el textbox. (También Valida)
[DataType(DataType.EmailAddress)]

Genera el formato en el View a través de JQuery de tipo link en las listados y textbox. (También Valida)
[DataType(DataType.Url)]

Genera el formato en el View a través de JQuery de tipo link en las listados y textbox. (También Valida)
[DataType(DataType.MultilineText)]

Genera un textbox en el view tipo multiline


using System.ComponentModel.DataAnnotations.Schema;
[NotMapped]
public int Edad { get { return DateTime.Now.Year - FechaNacimiento.Year; } }
Por normalización los campo calculados no van en las tablas, este DataAnnotations evita que este campo se cree y además lo
crea sólo lectura con el valor desde el arranque. Ojo que debe invocar la librería que está en la cabecera.
[Column("NombreCompleto")]
public string Nombre { get; set; }
Proporciona un el nombre a la columna en la tabla sin necesidad que sea el mismo de la clase.
[Table("TblEmpleados")]
Public Class Empleados
{
}
Renombra la tabla en el modelo de datos, para que no se llame igual que la clase
[ForeignKey("TipoDocumento")]
public virtual TipoDocumento TipoDoc { get; set; }
Permite vincular las relaciones de ambas clases si el nombre de la propiedad es diferente, si ambas propiedades de llaman
iguales no se necesita este DataAnnotations.
[DataType(DataType.Currency)]

[DisplayFormat(DataFormatString = "{0:C2}", ApplyFormatInEditMode = false)]

public decimal Precio { get; set; }


Permite ingresar números tipo moneda con dos decimales.

[DataType(DataType.Currency)]

[DisplayFormat(DataFormatString = "{0:N2}", ApplyFormatInEditMode = false)]


public float Stock { get; set; }
Valores numéricos con dos decimales.
[ScaffoldColumn(false)]

DropDownList ordenarlo y agregar un Ítems de Seleción.

@Html.DropDownList("IdTipoDocumento", null, htmlAttributes: new { @class = "form-control" })

Este objeto del View, que visualiza un listado de componentes puede ser manipulado desde el controlador de esta manera:
// GET: Personas/Create
public ActionResult Create()
{
var lista = db.TipoDocumentoes.ToList();
lista.Add(new TipoDocumento { IdTipoDocumento = 0, DescTipoDocumento = "[Seleccione Documento]" });
lista = lista.OrderBy(c => c.DescTipoDocumento).ToList();
ViewBag.IdTipoDocumento = new SelectList(lista, "IdTipoDocumento", "DescTipoDocumento");
return View();
}
Donde la lista es traspasada, para posteriormente agregar un Ítems y ser ordenada para su visualización.

Evitar la Eliminación de Borrado en cascada


Para evitar la eliminación de registros en cascada debemos sobrescribir un método en el archivo de contexto que tenemos en el
proyecto.

protected override void OnModelCreating(DbModelBuilder modelBuilder)

{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
Esto provocará un error en la capa o procesos que invoque una eliminación de forma automática, la que deberá ser capturada con
catch para evitar el volcamiento de la aplicación.

Generar enum públicos para atributos


Para generar ciertos estados o listados de constantes enumeradas se puede utilizar una colección para generar estados de forma
simple:
public enum OrdenEstado
{
Creada,
EnProgreso,
Despachada,
Entregada
}

La clase que necesite esta colección la debe incorporar de la siguiente manera:


public OrdenEstado OrdenEstado { get; set; }

Seguridad en Facebook
Para lograr la autentificación con Facebook debemos considerar los siguientes pasos:
 Crear una aplicación MVC 5
 Entrar al portal de Facebook Developers (https://developers.facebook.com/)
 Seguir los pasos en Facebook para conseguir dos parámetros importantes para llevarlos a la aplicación:
1. Identificador de la aplicación:
2. Clave secreta de la aplicación
 Una vez conseguidos ir al proyecto a la carpeta App_Start – archivo Startup.Auth.cs habilitar la línea que esta
comentada
app.UseFacebookAuthentication(
appId: "Identificador de la aplicación",
appSecret: "Clave secreta de la aplicación");
 Listo nuestra aplicación ya cuenta con autentificación facebook.

Generar Seguridad en MVC 5


-
Seguridad y privilegios en controlador
Para acceder a las opciones del controlador, por defecto se puede entrar a todo, para restringir el acceso vamos a
estudiar los diferentes privilegios y sus alcances.
Etiqueta Ejemplo
[Authorize] : Exige a los usuarios estén todos [Authorize]
autentificados o logueado antes de entrar al public class MedicosController : Controller
controlador. {
}

[Authorize]: También se puede aplicar a nivel de public class MedicosController : Controller


acción, de esa manera los no logueado pueden {
ser stock de productos pero no modificar datos. [Authorize]
public ActionResult Create()
[Authorize(User = "fvaldes@tie.cl")] : permite {
ver los contenidos a sólo el usuario de la lista. return View();
}
}
[Authorize(Roles= "Create")]
[Authorize(Roles= "View")]: Crea los permisos a Authorize(Roles= "Create")]
las acciones a través de los Roles asignados por public ActionResult Create()
el súper usuario. {
return View();
}

[AllowAnonymous]: Lo contrario a lo anterior, [Authorize]


permite ver contenidos son estar autentificado, public class MedicosController : Controller
es muy útil cuando decides etiquetar todo el {
controlador con Authorize y solo algunas [AllowAnonymous]
acciones puntuales las dejas Anonymous. public ActionResult Create()
{
return View();
}
}

Crear Roles
Una de las opciones es crearlo en el primer evento del proyecto, lo genera el Global.asax con los siguientes pasos:

Primero: Ponemos las librerías necearías para llevar a cabo las opciones de crear usuario y roles

using System.Data.Entity;
using MVC5_VisitaMedica.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;

Segundo: Creamos una conexión con el contexto de seguridad, ojo con el de seguridad...no con el contexto creado por
nosotros."DefaultConnection", debemos tomar la precaución que en el webconfig ambas conexiones apuntes a la misma
base de datos, es ideal no obligatorio.

protected void Application_Start()


{
ApplicationDbContext db = new ApplicationDbContext();

Tercero: programamos el código que agrega los roles, siempre y cuando no existan en la tablas Roles.
private void CrearRoles(ApplicationDbContext db)
{
var rolesManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(db));
//Verifica la existencia del Rol en la base de Datos.
if (!rolesManager.RoleExists("View"))
{
rolesManager.Create(new IdentityRole("View"));
}
if (!rolesManager.RoleExists("Edit"))
{
rolesManager.Create(new IdentityRole("Edit"));
}
if (!rolesManager.RoleExists("Create"))
{
rolesManager.Create(new IdentityRole("Create"));
}
if (!rolesManager.RoleExists("Delete"))
{
rolesManager.Create(new IdentityRole("Delete"));
}
if (!rolesManager.RoleExists("APM"))
{
rolesManager.Create(new IdentityRole("APM"));
}
if (!rolesManager.RoleExists("ADMIN"))
{
rolesManager.Create(new IdentityRole("ADMIN"));
}
}

Crear usuarios o super usuario


private void CrearSuperUsuario(ApplicationDbContext db)
{
//Permite crear usuarios sin registrarse
var usuarioManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
var usuario = usuarioManager.FindByName("fvaldes@tie.cl");
if (usuario == null)
{
usuario = new ApplicationUser
{
UserName = "fvaldes@tie.cl",
Email = "fvaldes@tie.cl"
};
usuarioManager.Create(usuario, "Fvaldes1234.");
}
}

Agrega Roles a usuarios


private void AgregarPrivilegiosSuperUsuario(ApplicationDbContext db)
{
var usuarioManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
var rolesManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(db));
var usuario = usuarioManager.FindByName("fvaldes@tie.cl");
//El usuario NO pertenece al Rol View
if (!usuarioManager.IsInRole(usuario.Id, "View"))
{
usuarioManager.AddToRole(usuario.Id,"View");
}
if (!usuarioManager.IsInRole(usuario.Id, "ADMIN"))
{
usuarioManager.AddToRole(usuario.Id, "ADMIN");
}
}

También podría gustarte