martes, 23 de febrero de 2016

Web application MVC con Entity Framework - autentificacion - SQL Express

Necesitaba crear un proyecto web, que tenga un administrador con seguridad y una pagina principal visible para el usuario.

Tome como ejemplo Contoso University de la página de asp.net sin autenticación
http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application

Con autenticación
http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application
  1. Iniciar Visual Studio
  2. Archivo / nuevo / proyecto
  3. Plantillas / Visual #C / web / Aplicacion Web ASP.NET
  4. Le damos un nombre al proyecto
  5. Aceptar
  6. Seleccionar plantilla MVC
  7. En la misma Cambiar autentificación marcar cuentas de usuario individuales
  8. Corremos el proyecto en nuestro browser de preferencia y obtendremos la info y el template default.

Crear modelos desde una base existente
http://www.asp.net/mvc/overview/getting-started/database-first-development/creating-the-web-application

Crear nuestros modelos
En el explorador de soluciones, clic derecho sobre la carpeta Moldels / Agregar / clase

En el ejemplo de Contoso tenemos tres modelos
Uno puede crear los modelos que uno desee.

En relaciones de 1 a muchos, del lado del muchos va el id.
En la relacion de 1 va la coleccion:
public virtual ICollection Enrollments { get; set; } 

En la relacion de muchos va el objeto:
public virtual Student Student { get; set; } 



  1. Crear el contexto de la base de datos
  2. Clic derecho sobre el proyecto
  3. Crear carpeta
  4. DAL
  5. Clic derecho sobre la carpeta DAL
  6. Agregar clase  SchoolContext.cs



using ContosoUniversity.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace ContosoUniversity.DAL
{
    public class SchoolContext : DbContext
    {
    
        public SchoolContext() : base("SchoolContext")
        {
        }
        
        public DbSet<Student> Students { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Course> Courses { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }
}
El string de base("SchoolContext") lo vamos a usar en Web.config
Vamos a añadirlo en el tag connectionStrings.

<add name="SchoolContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity1;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
Originalmente el proyecto viene con una conexión Default, la cual vamos a modificar porque en mi caso no quiero usar una LocalDb quiero usar una conexión SQL Express de mi computadora.

 <connectionStrings>
    <add name="DefaultConnection"
    connectionString="Data Source=ORG\SQL;
    Initial Catalog=dbcontoso;Integrated Security=SSPI;"
    providerName="System.Data.SqlClient" />
   <add name="SchoolContext" connectionString="Data Source=ORG\SQL;Initial Catalog=dbcontoso;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
  </connectionStrings>

Al final del Web.config tambien debemos modificar el entityFramework ya que esta con LocalDB y nosotros vamos a usar SQL Express

<entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="System.Data.SqlServerCe.4.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

Crear vistas y controladores

  1. Clic derecho sobre la carpeta de Agregar / Nuevo elemento con scaffolding
  2. Seleccionar Controlador de MVC5 con vistas que usan EntityFramework
  3. Escribimos la clase modelo a la cual le vamos a crear la vista y el controlador (Se debe hacer para cada modelo nuevo que creamos)
  4. Seleccionamos el contexto de datos en este caso SchoolContext
  5. Checar todo lo relacionado a vistas
  6. Escribir el nombre del controlador
  7. Agregar
Habilitar Migracion
Herramientas
Administrador de paquetes
Consola del administrador de paquetes
En la linea de comando PM>

enable-migrations -contexttypename SchoolContext
A lo que termine de ejecutar el comando veremos en el explorador de soluciones que se creo la carpeta de Migrations en nuestro proyecto con una clase de configuracion dentro, en este archivo es donde vamos a inicializar nuestra base.

namespace ContosoUniversity.Migrations
{
   using System;
   using System.Collections.Generic;
   using System.Data.Entity.Migrations;
   using System.Linq;
   using ContosoUniversity.Models;

   internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.DAL.SchoolContext>
   {
      public Configuration()
      {
         AutomaticMigrationsEnabled = false;
      }

      protected override void Seed(ContosoUniversity.DAL.SchoolContext context)
      {
         var students = new List<Student>
            {
                new Student { FirstMidName = "Carson",   LastName = "Alexander", 
                    EnrollmentDate = DateTime.Parse("2010-09-01") },
                new Student { FirstMidName = "Meredith", LastName = "Alonso",    
                    EnrollmentDate = DateTime.Parse("2012-09-01") },
                new Student { FirstMidName = "Arturo",   LastName = "Anand",     
                    EnrollmentDate = DateTime.Parse("2013-09-01") },
                new Student { FirstMidName = "Gytis",    LastName = "Barzdukas", 
                    EnrollmentDate = DateTime.Parse("2012-09-01") },
                new Student { FirstMidName = "Yan",      LastName = "Li",        
                    EnrollmentDate = DateTime.Parse("2012-09-01") },
                new Student { FirstMidName = "Peggy",    LastName = "Justice",   
                    EnrollmentDate = DateTime.Parse("2011-09-01") },
                new Student { FirstMidName = "Laura",    LastName = "Norman",    
                    EnrollmentDate = DateTime.Parse("2013-09-01") },
                new Student { FirstMidName = "Nino",     LastName = "Olivetto",  
                    EnrollmentDate = DateTime.Parse("2005-08-11") }
            };
         students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s));
         context.SaveChanges();

         var courses = new List<Course>
            {
                new Course {CourseID = 1050, Title = "Chemistry",      Credits = 3, },
                new Course {CourseID = 4022, Title = "Microeconomics", Credits = 3, },
                new Course {CourseID = 4041, Title = "Macroeconomics", Credits = 3, },
                new Course {CourseID = 1045, Title = "Calculus",       Credits = 4, },
                new Course {CourseID = 3141, Title = "Trigonometry",   Credits = 4, },
                new Course {CourseID = 2021, Title = "Composition",    Credits = 3, },
                new Course {CourseID = 2042, Title = "Literature",     Credits = 4, }
            };
         courses.ForEach(s => context.Courses.AddOrUpdate(p => p.Title, s));
         context.SaveChanges();

         var enrollments = new List<Enrollment>
            {
                new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Alexander").StudentID, 
                    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID, 
                    Grade = Grade.A 
                },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Alexander").StudentID,
                    CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID, 
                    Grade = Grade.C 
                 },                            
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Alexander").StudentID,
                    CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID, 
                    Grade = Grade.B
                 },
                 new Enrollment { 
                     StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
                    CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID, 
                    Grade = Grade.B 
                 },
                 new Enrollment { 
                     StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
                    CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID, 
                    Grade = Grade.B 
                 },
                 new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
                    CourseID = courses.Single(c => c.Title == "Composition" ).CourseID, 
                    Grade = Grade.B 
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Anand").StudentID,
                    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Anand").StudentID,
                    CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID,
                    Grade = Grade.B         
                 },
                new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Barzdukas").StudentID,
                    CourseID = courses.Single(c => c.Title == "Chemistry").CourseID,
                    Grade = Grade.B         
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Li").StudentID,
                    CourseID = courses.Single(c => c.Title == "Composition").CourseID,
                    Grade = Grade.B         
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Justice").StudentID,
                    CourseID = courses.Single(c => c.Title == "Literature").CourseID,
                    Grade = Grade.B         
                 }
            };

         foreach (Enrollment e in enrollments)
         {
            var enrollmentInDataBase = context.Enrollments.Where(
                s =>
                     s.Student.StudentID == e.StudentID &&
                     s.Course.CourseID == e.CourseID).SingleOrDefault();
            if (enrollmentInDataBase == null)
            {
               context.Enrollments.Add(e);
            }
         }
         context.SaveChanges();
      }
   }
}
Ejecutar la migracion en la linea de comando
add-migration InitialCreate
update-database
Correr la app


NOTA;
Para llamar varios modelos en una sola vista debemos inicializarlos con ViewBag en el controlador de la vista donde los queremos usar.
Ejemplo: Quiero usar todos los modelos en el home

En HomeController

 private TarjetasContext db = new TarjetasContext();
        public ActionResult Index()
        {
            ViewBag.Course = db.Course.ToList();
            ViewBag.Students = db.Students.ToList();
            ViewBag.Enrollments = db.Enrollments.ToList();
            return View();
        }

En la vista donde los vamos a usar
@using contoso.Models;

@{
    var course = (List<Course>)ViewBag.Course;
    var students = (List<Students>)ViewBag.Students;
    var  enrollments= (List<Enrollments>)ViewBag.Enrollments;
}

                           @foreach (var item in students)
                            {
                                <div><img src="/img/@(item.Name).png"></div>
                            }


Añadir css y js:

En App_start / BundleConfig.cs / BundleConfig / Register Bundles (BundlesCollection) estan los js y los css para agregarlos.


Para establecer EF

  • Clic derecho sobrel el proyecto
  • Administrar paquetes NuGet
  • Buscar en linea
  • EntityFramework
  • instalar


Determinar que paginas llevan autentificacion y cuales no.
Para añadir autentificacion en el controlador añadimos
namespace contoso.Controllers
{
    [Authorize]
    public class StudentsController : Controller
    {

Para dejar que todo el mundo pueda verla

namespace contoso.Controllers
{
    [AllowAnonymous]
    public class HomeController : Controller
    {