Sie sind auf Seite 1von 92

PROGRAMACIN DE

APLICACIONES DISTRIBUIDAS

Tutorial ASP.NET MVC 5


implementando Bootstrap
y Vista Razor

Paul, Vctor
Leonardo
Legajo 30865

Introduccin
Visual Studio es un IDE o entorno de desarrollo integrado. Al igual que usted utiliza
Microsoft Word para escribir documentos, vamos a usar un IDE para crear
aplicaciones.
Este tutorial le ensear los conceptos bsicos de la construccin de una aplicacin
Web ASP.NET MVC 5 para Visual Studio 2013. Implementando un framework
denominado Bootstrap para crear las interfaces web con JavaScrip y CSS, un motor
de vistas llamado Razor el cual fue implementado desde la versin 3 de ASP.NET
MVC, est basado en plantillas de vistas y tiene una extensin de archivo .cshtml.
Adems este mismo provee una manera elegante de crear una salida HTML con c#.
Razor minimiza el nmero de caracteres y tipeo necesario para escribir una plantilla de
vista y as permitir un trabajo rpido.
Tambin puede hacer que la aplicacin est disponible a travs de Internet mediante el
despliegue a un proveedor de hosting. Microsoft ofrece alojamiento web gratuito para
un mximo de 10 sitios web en una cuenta de prueba gratuita de Windows Azure
http://azure.microsoft.com/en-us/pricing/free-trial/?WT.mc_id=A443DD604
MVC (modelo-vista-controlador) es un patrn para el desarrollo de aplicaciones que
posee buena arquitectura, comprobable y fcil de mantener.
Las aplicaciones basadas en MVC contienen:
Modelos: Clases que representan los datos de la aplicacin y que lgica de validacin
usa para hacer cumplir las reglas de negocio para esos datos.
Vista: archivos de plantilla que la aplicacin utiliza para generar dinmicamente
respuestas HTML.
Controlador: clases que manejan las solicitudes entrantes de navegacin, recuperar
los datos del modelo, y luego especificar plantillas de vista que devuelven una
respuesta al navegador.
Primeros Pasos:
Comience instalando y ejecutando Visual Studio Express 2013 para Web del siguiente
enlace:
http://www.visualstudio.com/downloads/download-visual-studio-vs#d-2013express
Una Vez instalado y ejecutado el Visual Studio podemos observar en la pantalla
principal distintas secciones como la barra de herramientas en la parte superior que
muestra mltiples opciones disponibles para usted. Tambin hay un men que ofrece
otra manera de realizar tareas en el IDE. (Por ejemplo, en lugar de seleccionar Nuevo
proyecto desde el inicio la pgina, puede utilizar el men y seleccione Archivo > Nuevo
proyecto.)

Creacin de su primera aplicacin


La siguiente imagen muestra cmo crear un Nuevo Proyecto. Comience seleccionando
Visual C # a la izquierda, a continuacin, Web y seleccione Aplicacin Web
ASP.NET. Ingrese el nombre de su proyecto, en este caso utilizaremos "MvcMovie".
Seleccione donde desea guardar su proyecto, por defecto Visual Studio lo guarda en
su carpeta Projects. Y luego haga clic en Aceptar.

En el nuevo proyecto de ASP.NET de dilogo, haga clic en la plantilla MVC y luego


haga clic en Aceptar.

Visual Studio utiliza una plantilla predeterminada para el proyecto ASP.NET MVC que
acaba de crear, por lo que tiene una aplicacin de trabajo en este momento sin hacer
nada! Este es un simple "Hola Mundo!" proyecto, y es un buen lugar para comenzar su
aplicacin.

Presione F5 para ejecutar la aplicacin web. Luego se abrira automticamente un


navegador y muestra la pgina principal de la aplicacin. A continuacin podemos
observar que la barra de direcciones del navegador dice localhost: 52947 y no algo
como example.com. Esto se debe a localhost siempre apunta a su propio equipo local,
que en este caso se est ejecutando la aplicacin que acaba de construir. En cuanto al
puerto (52947), se le asigna uno aleatorio.

A continuacin podemos observar que en la parte superior derecho de la pgina


aparece el icono IMAGEN. Al hacer click en el mismo se desplazara el men por
defecto de la plantilla el cual contiene campos como inicio, acerca de, registrar e inicio
de sesin

AGREGAR CONTROLADOR
A continuacin aprenderemos como aplicar el patrn MVC.
Comenzaremos creando una clase Controlador como se muestra en la imagen
siguiente:

A continuacin se abrir una ventana para elegir el tipo de controlador que deseamos
agregar, en este caso seleccionamos la opcin Controlador de MVC 5: En
blanco y hacemos click en agregar.

Ahora nos pedir que ingresemos el nombre del controlador, en este caso
ingresaremos HolaMundo como modo de ejemplo y presionamos agregar.

En la siguiente imagen podemos observar que en el Explorador de Soluciones se


encuentra el controlador que acabamos de crear HolaMundo.cs y una carpeta Vistas

\ HolaMundo.

Abrimos el controlador que creamos y reemplazamos el cdigo que contiene por el


siguiente:

Podemos observar la clase controlador HolaMundo que es la que creamos con


anterioridad, y dos mtodo ndice y Bienvenido, los cuales devuelven directamente
una cadena. Al Ejecutar la aplicacin presionando F5 y agregando en la barra de
direcciones /HelloWorld observaremos el resultado del cdigo ingresado.
ndice es el mtodo por defecto que se llama en un controlador si no se especifica de
forma explcita.

La lgica de enrutamiento URL predeterminado utilizado por ASP.NET MVC utiliza el


siguiente formato para determinar qu cdigo invocar:
/ [Controller] / [ActionName] / [Parameters]

Controlador: determina la clase del controlador a ejecutar


Nombre de la Accin: determina el mtodo de accin de la clase a ejecutar.
Parmetros: especifica datos de rutas
LA siguiente imagen especifica cmo establecer el formato para la ruta
App_Start/RouteConfig.cs

A continuacin ejecutamos la aplicacin y en la barra de direccin ingresamos


http://localhost:52947/HelloWorld/Welcome como se muestra en la imagen.

Ahora modificaremos el mtodo Welcome con el fin de agregar parmetros para el


controlador.
Cambiamos el mtodo Welcome por el siguiente cdigo:

10

Podemos observar que el parmetro numTime =1 toma el valor 1 por defecto en el


caso que no se le asigne un valor parmetro.

Reemplace el mtodo Welcome por el siguiente cdigo:

Ejecute la aplicacin e introduzca la siguiente URL:


HelloWorld/Welcome/3?name=Rick

http: // localhost:xxx /

En la imagen anterior se puede ver que el tercer segmento URL se corresponda con
el parmetro de ruta ID. El mtodo Welcome contiene un parmetro (ID) que coincide
con la URL especificada en el mtodo RegisterRoutes.
En las aplicaciones ASP.NET MVC es tpico pasar parmetros como datos de ruta
(como lo muestra la imagen anterior) que como cadena de consultas. Tambin se
puede agregar una ruta para los parmetros name y numtimes en

App_Start\RouteConfig.cs.
Agregue el siguiente cdigo en RouteConfig.cs:
Presione

F5

en

la

barra

de

direcciones

localhost:xxx/HelloWorld/Welcome/Scott/3

11

ingrese

la

siguiente

ruta:

Como pudimos observar hasta aqu aplicamos los conceptos de Vista Controlador
(VC) del modelo MVC, es decir la visin y el trabajo del controlador.

Agregar una vista


En esta seccin vamos a modificar la clase HelloWorldController para utilizar archivos
de vista de plantilla para encapsular el proceso de generar respuestas HTML a un
cliente.
Como se vio en seccin anterior el mtodo Index devolva una cadena con un mensaje
que se encontraba en la clase controlador. Ahora vamos a cambiar dicho Index de tal
forma que devuelva un objeto View ingresando el siguiente cdigo.

Este mtodo utiliza una plantilla de vista para generar una respuesta HTML al
navegador. Tanto el mtodo controlador (tambin conocidos como mtodos de
accin ), como este Index , generalmente devuelven un ActionResult (o una
clase derivada de ActionResult ) y no tipos primitivos como cadena.
12

Haga clic derecho en la carpeta HelloWorld de views y haga clic en Agregar y,


a continuacin, haga clic MVC 5 Ver Pgina con (Diseo Razor).

En el Cuadro de Dilogo, ingrese Index, y luego haga clic en Aceptar. En la


Seleccin Pgina de Diseo, acepte el valor predeterminado _Layout.cshtml y
haga clic en Aceptar. En el cuadro de dilogo anterior, la carpeta Shared est
seleccionada en la izquierda del panel. Si tuvieras un archivo de diseo
personalizado en otra carpeta,

13

puede

seleccionarlo.

Podemos observar que el archivo Index.cshtml fue cread HelloWorld.

14

Agregue el siguiente Cdigo:

Haga clic derecho en el archivo Index.cshtml y seleccione Ver en el


explorador

15

16

Cambiar las vistas y el diseo de pginas


Para realizar esta accin vamos a Views/Shared/_Layout.cshtml en el
explorador de soluciones.

La Plantilla de diseo le permite especificar el formato contenedor HTML de su


sitio en un lugar y luego aplicarlo en varias pginas en su sitio. RenderBody es
un marcador de posicin en el que todas las pginas especficas de vista que
cree se presentan, "envuelto" en la pgina de diseo. Por ejemplo, si
selecciona el enlace Acerca de, View\Home\About.cshtml vera que se
representa dentro del mtodo RenderBody.

Para cambiar el contenido del ttulo. Primero cambie el ActionLink en la plantilla


de diseo de "Application name" a "MVC Movie" y el controlador
17

de Inicio de Pelculas. El archivo de diseo completo se muestra a


continuacin:

A continuacin ejecute la aplicacin y observe como se cambio el titulo a MVC


Pelcula. Tambin logramos que este ttulo se mantenga en todas las
pestaas.

El siguiente cdigo Razor establece el diseo de la pagina


@{

18

Layout = "~/Views/Shared/_Layout.cshtml";
}

Examine el archivo Views\_ViewStart.cshtml, que contiene exactamente el


mismo beneficio que Razor. El archivo Views\_ViewStart.cshtml define el
diseo comn que todas las vistas utilizarn, por lo tanto, puede comentar o
eliminar el cdigo del archivo Views\HelloWorld\Index.cshtm.

Puede utilizar la propiedad Layout para establecer una vista de diseo


diferente, o se establece en nulo por lo que no se utilizar ningn archivo de
diseo.
Ahora, vamos a cambiar el ttulo de la vista ndice.
Abrir MvcMovie\views\HelloWorld\Index.cshtml. Hay dos lugares para hacer un
cambio: en primer lugar, el texto que aparece en el ttulo del navegador, y luego
en el encabezado secundario (el elemento <h2>). Usted va a hacer de ellos un
poco diferente para que pueda ver que poco cambio el cdigo en la aplicacin.
@{
ViewBag.Title = "Movie List";
}
<h2>My Movie List</h2>
<p>Hello from our View Template!</p>

19

Pasar datos del Controlador a la Vista


La Clase Controller se invoca en respuesta a una solicitud de URL entrante.
Una clase controlador es donde se escribe el cdigo que maneja las solicitudes
entrantes de navegacin, recuperan datos de una base de datos, y decide qu
tipo de respuesta devolver al navegador. Las plantillas vistas pueden utilizarse
desde un controlador para generar y dar formato a una respuesta HTML en el
navegador.
Los controladores son responsables de proporcionar cualquier dato u objetos
que se requiera para que una plantilla de vista entregue una respuesta al
navegador. Una buena prctica: Una plantilla de vista nunca debe realizar la
lgica de negocio o interactuar directamente con una base de datos. En
cambio, una plantilla de vista debe trabajar slo con los datos que se
proporcionan a ella por el controlador. El mantenimiento de esta "separacin de
intereses" ayuda a mantener el cdigo limpio, comprobable y ms fcil de
mantener.
Actualmente, el mtodo de accin Welcome en la case HelloWorldController
toma los parmetros nombre y un numTimes y luego da salida a los valores
directamente en el navegador. En lugar de tener el controlador render como
una cadena, vamos a cambiar el controlador y utilizar una plantilla de vista en
su lugar. La plantilla de vista va a generar una respuesta dinmica, lo que
significa que usted necesita pasar apropiados bits de datos del controlador a la
vista, con el fin de generar una respuesta. Puede hacer esto haciendo que el
controlador ponga los datos dinmicos (parmetros) que la plantilla de vista
necesita en un objeto ViewBag para que la plantilla de vista pueda acceder.
Vuelva al archivo HelloWorldController.cs y cambie el mtodo Welcome para
agregar un mensaje y el valor NumTimes al objeto ViewBag. ViewBag es un
objeto dinmico, lo que significa que puedes poner lo que quieras en el; el
objeto ViewBag tiene propiedades no definido hasta que coloque algo en su
interior. El modelo ASP.NET MVC mapea automticamente los parmetros
name y numTimes de la cadena de consulta en la barra de direcciones a los
parmetros de su mtodo. El archivo HelloWorldController.cs archivo se ve as:
using System . Web ;
using System . Web . Mvc ;
namespace MvcMovie . Controllers
{
public class HelloWorldController : Controller
{
public ActionResult Index ()
{
return View ();
}

20

public ActionResult Welcome ( string name , int numTimes = 1 )


{
ViewBag . Message = "Hello " + nombre ;
ViewBag . NumTimes = numTimes ;
devolver Ver ();
}
}
}

Ahora el objeto ViewBag contiene datos que se pasar a la vista de forma


automtica. Despus, usted necesita una vista de plantilla Welcome! En
el men Build, seleccione Generar solucin (o Ctrl + Shift + B) para
asegurarse de que el proyecto se compila. Haga clic derecho en la carpeta
Views\HelloWorld y haga clic en Agregar y, a continuacin, haga clic en
Pginas de vistas de MVC 5 con Diseo (Razor).
En el Cuadro de Dilogo ingrese Bienvenido y haga clic en Aceptar . A
continuacin acepte el valor predeterminado _Layout.cshtml y haga clic
en Aceptar.
En el archivo Welcome.cshtml vamos a crear un bucle que dice "Hola" tantas
veces como el usuario diga. El archivo Welcome.cshtml se muestra completo a
continuacin.

Ejecute la aplicacin y vaya a la siguiente URL:


http://localhost:xx/HelloWorld/Welcome?name=Scott&numtimes=4
Ahora, los datos se toman de la URL y se pasan al controlador usando
el modelo binder. El controlador empaqueta los datos en un objeto ViewBag y
pasa ese objeto a la vista. La vista a continuacin, muestra al usuario los datos
como HTML.

21

En el ejemplo anterior, utilizamos un objeto ViewBag para pasar datos desde el


controlador a una vista. Al final del tutorial, vamos a utilizar un modelo de vista
para pasar datos de un controlador a una vista.

Agregar Modelo
En esta seccin vamos a aadir en una base de datos algunas clases de la
gestin de las pelculas. Estas clases sern la parte del "modelo" de la
aplicacin ASP.NET MVC.
Vamos a usar una tecnologa de acceso a datos de .NET Framework conocido
como el Entity Framework para definir y trabajar con estas clases de modelo. El
Entity Framework (a menudo referido como EF) apoya un paradigma de
desarrollo llamado Code Firs (Primer Codigo). Code First le permite crear
objetos de modelo escribiendo clases simples. (Estos son tambin conocidos
como clases POCO, de " plain-old CLR."), Entonces usted puede tener la base
de datos creada sobre la marcha de sus clases, lo que permite un flujo de
trabajo de desarrollo muy limpio y rpido.
Agregar Clases al Modelo
En el Explorador de soluciones, haga clic derecho en la carpeta Models,
seleccione Agregar y, a continuacin, seleccione la clase.

22

En el cuadro de dialogo ingrese el nombre Movie

En la clase creada agregue las siguientes cinco propiedades a la clase Movie:

23

Usaremos la clase Movie para representar pelculas en una base de


datos. Cada instancia de un objeto pelcula corresponder a una fila dentro de
una tabla de base de datos, y cada propiedad de la clase Movie se proyectar
en una columna en la tabla.
En el mismo archivo, agregue la siguiente clase MovieDBContext:

La clase MovieDBContext representa el contexto de la base de datos Movie de


Entity Framework, que se encarga de buscar, almacenar y actualizar Instancias
de la clase de Movie en una base de datos. El MovieDBContext deriva de la
clase DbContext proporcionada por el Entity Framework. Con el fin de hacer
referencia a DbContext y DbSet, es necesario agregar la librera using
System.Data.Entity; en la parte superior izquierda del archivo.

Con esto lo que hicimos es agregar un modelo (el M del MVC).

24

Creacin de una cadena de conexin y trabajar con


SQL Server LocalDB

En esta seccin vamos a aadir explcitamente una cadena de conexin en el


archivo Web.config de la aplicacin.

La clase MovieDBContext que ha creado se encarga de conectar las bases de


datos y mapeo del objeto Movie a los registros de la base de datos. Una
pregunta que podra preguntar, sin embargo, es cmo especificar qu base de
datos va a conectar. En realidad no tiene que especificar qu base de datos
utilizar, Entity Framework utilizar por defecto LocalDB.

SQL Server Express LocalDB


LocalDB es una versin ligera del motor de base de datos SQL Server Express
que se inicia en la demanda y se ejecuta en modo de usuario. LocalDB ejecuta
en un modo especial de ejecucin de SQL Server Express que le permite
trabajar con bases de datos como archivos .mdf. Normalmente, los archivos de
base de datos LocalDB se mantienen en la carpeta App_Data de un proyecto
web.
SQL Server Express no est recomendado para su uso en la produccin de
aplicaciones web. LocalDB, en particular, no debe utilizarse para la produccin
de una aplicacin web, ya que no est diseado para trabajar con IIS. Sin
embargo, una base de datos LocalDB se puede migrar cmodamente a SQL
Server o SQL Azure.
En Visual Studio 2013 (y en 2012), LocalDB se instala por defecto con Visual
Studio.
Por defecto, el Marco de la entidad busca una cadena de conexin con el
mismo nombre que la clase de contexto del objeto (MovieDBContext para este
proyecto).

Abra la raz de la aplicacin Web.config como se muestra a continuacin. (No


el archivo Web.config de la carpeta Views).

25

Busque en el cdigo del mismo el elemento <connectionStrings> :

Agregue la siguiente cadena de conexin al elemento <connectionStrings> en


el archivo Web.config.:
<add name="MovieDBContext"
connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|
DataDirectory|\Movies.mdf;Integrated Security=True"

26

providerName="System.Data.SqlClient"
/>

El siguiente ejemplo muestra una parte del archivo Web.config con la nueva
cadena de conexin aadido:
<connectionStrings>
<add name="DefaultConnection" connectionString="Data
Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnetMvcMovie-20130603030321.mdf;Initial Catalog=aspnet-MvcMovie20130603030321;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="MovieDBContext" connectionString="Data
Source=(LocalDB)\v11.0;AttachDbFilename=|
DataDirectory|\Movies.mdf;Integrated Security=True"
providerName="System.Data.SqlClient"
/>

La primera cadena de conexin se llama DefaultConnection y se utiliza para la


base de datos de miembros para controlar quin puede acceder a la
aplicacin.
La segunda cadena de conexin especifica una base de datos LocalDB
llamado Movie.mdf ubicado en la carpeta App_Data.

El nombre de la cadena de conexin debe coincidir con el nombre de la clase


DbContext.

pblico de clase MovieDBContext : DbContext


{
pblicas DbSet < Pelcula > Pelculas { consiguen ; set ; }
}
}

Acceso a los datos de su modelo desde un


controlador

27

En esta seccin vamos a crear una nueva clase MoviesController y escribir un


cdigo para recupera los datos del vdeo y mostrarlo en el navegador utilizando
una plantilla de vista.
Generar la aplicacin antes de pasar al siguiente paso. Si no generar la
aplicacin, usted obtendr un error al agregar un controlador.
Para Generar la aplicacin vaya a al men Depurar/GenerarMvcMovie.
En el Explorador de soluciones, haga clic en la carpeta Controllers y luego
haga clic en Agregar y, a continuacin Controlador.

En el cuadro de dilogo Agregar Scaffold, haga clic en Controlador de MVC 5


convistas que usa Entity Framework, y luego haga clic en Agregar.

28

Para el campo nombre del controlador ingrese MoviesController.

Seleccione Movie (MvcMovie.Models) para la clase de modelo.

Seleccione MovieDBContext (MvcMovie.Models) para la clase de


contexto de datos.

La siguiente imagen muestra el cuadro de dilogo completado.

29

Haga clic en Agregar. (Si se produce un error, es probable que no


construyeron la aplicacin antes de comenzar la adicin del controlador.) Visual
Studio crea los siguientes archivos y carpetas:

Un archivo MoviesController.cs en la carpeta Controllers.

Una carpeta Views\Movies. Con los siguientes archivos.

Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml y Index.cshtml.

Visual Studio crea automticamente el CRUD (crear, leer, actualizar y


eliminar) los mtodos de accin y puntos de vista (la creacin automtica de
mtodos y puntos de vista de accin CRUD se conoce como scaffolding).
Ahora tiene una aplicacin web completamente funcional que le permite crear,
listar, editar y eliminar entradas de cine.
Ejecute la aplicacin y haga clic en el enlace MVC Movie (o busque
el controlador Movie aadiendo /Movies a la direccin URL en la barra de
direcciones de su navegador). Debido a que la aplicacin se basa en la ruta por
defecto (definido en el archivo App_Start\RouteConfig.cs), el navegador http://
localhost:xxxxx/Movies se redirecciona al mtodo ndex del controlador
Movies. En
otras
palabras,
el
navegador
de
peticin http://localhost:xxxxx/Movies es efectivamente el mismo que el
navegador peticin http://localhost:xxxxx/Movies/ndex. El resultado es una lista
vaca de pelculas, porque no se ha aadido ninguna todava.

30

Crear una pelcula


Seleccione el enlace Crear nuevo. Ingrese algunos detalles sobre una pelcula
y luego haga clic en el Crear botn.

31

Al hacer clic en el Crear botn hace que el formulario se ha publicado en el


servidor, donde la informacin de la pelcula se guarda en la base de datos y lo
redirecciona a la lista de las pelculas.

Evaluacin del cdigo generado


Abra el archivo Controllers/MoviesController.cs y examine el mtodo ndice.
public class MoviesController : Controller

32

{
private MovieDBContext db = new MovieDBContext();
// GET: /Movies/
public ActionResult Index()
{
return View(db.Movies.ToList());
}

Una peticin al controlador Movies devuelve todas las entradas en la


tabla Movie y luego pasa los resultados al Index de views. La siguiente lnea de
la clase MoviesController instancia un contexto de base de datos de la
pelcula, como se describi anteriormente. Usted puede utilizar el contexto de
la base de la pelcula para consultar, editar y borrar pelculas.
privado MovieDBContext db = nuevo MovieDBContext ();

Tipos de Modelos inflexibles y la palabra clave @Model


MVC tambin ofrece la posibilidad de pasar fuertemente objetos
mecanografiados a una plantilla de vista. Este tipo de enfoque inflexible
permite un mejor tiempo de compilacin de su cdigo y enriquecer
IntelliSense en el editor de Visual Studio. El mecanismo de scaffolding en Visual
Studio utiliza este enfoque con la clase MoviesController y las plantillas Views
cuando cre los mtodos y puntos de vista.
En el archivo controladores\MoviesController.cs examine
generado details. El mtodo Details se muestra a continuacin.

el

public ActionResult Details(int? id)


{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}

33

mtodo

El parmetro id generalmente se pasa como datos de la ruta, por ejemplo http://


localhost:xxxx/Movies/Details/1 fijarn el controlador para el controlador de la
pelcula, la accin de los details e id a 1. Tambin podran pasar en el id con
una cadena de consulta de la siguiente manera:
http://localhost:xxxx/Movies/Details?id=1
Si se encuentra una pelcula, se
pelcula a la vista Detalles:

pasa una

instancia

del modelo de

return View(movie);

Examine el contenido del archivo Views\Movies\Details.cshtml:

@model MvcMovie.Models.Movie
@{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>Movie</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Title)
</dt>
@*Markup omitted for clarity.*@
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
@Html.ActionLink("Back to List", "Index")
</p>

34

la

Al incluir una declaracin @Model en la parte superior del archivo de vista de


plantilla, puede especificar el tipo de objeto que la vista espera. Cuando
cre el controlador de la pelcula, Visual Studio incluye automticamente la
siguiente declaracin @Model en la parte superior del archivo Details.cshtml:
@model MvcMovie.Models.Movie
@Model le permite acceder a la pelcula que el controlador pasa a
la vista mediante el uso de un objeto de modelo que est inflexible. Por
ejemplo, en la pkantilla Details.cshtml, el cdigo pasa cada campo de pelcula a
los DisplayNameFor y DisplayFor HTML
Helpers
con el
objeto de
modelo inflexible. Los mtodos Crete y Edit y las plantillas de vista tambin
pasan un objeto de modelo de pelcula.
Examine Index.cshtml de la plantilla Views y el mtodo de Index en el
archivo MoviesController.cs. Observe cmo el cdigo crea un objeto de
lista cuando se llama al metodo de ayuda Views en el mtodo de la
accin Index.
public ActionResult Index()
{
return View(db.Movies.ToList());
}

Cuando
cre el controlador
de
la
pelcula,
Visual
Studio incluye
automticamente la siguiente declaracin @modelo en la parte superior del
archivo Index.cshtml:
@model IEnumerable<MvcMovie.Models.Movie>

Esta directiva @Model le permite acceder a la lista de pelculas que el


controlador pasa a la vista mediante el uso de un objeto modelo que
est inflexible.
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>

35

@Html.DisplayFor(modelItem => item.Genre)


</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<th>
@Html.DisplayFor(modelItem => item.Rating)
</th>
<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>
}

Dado
que
el
objeto del
modelo es
de
tipo
fuerte (como
un
IEnumerable <Movie> object), cada objeto de elemento en el circuito se escribe
como Movie.
Entre otras ventajas, esto significa que
compilacin comprobacin del
cdigo
IntelliSense completo en el editor de cdigo:

36

usted obtiene en tiempo de


y
la compatibilidad
con

Trabajando con SQL Server LocalDB

Entity Framework Code First detect que la cadena de conexin de base de


datos que se proporcion seal a una base de datos de pelculas que no
exista todava, as Code First cre la base de datos de forma automtica.
Usted puede comprobar que se ha creado mirando en la carpeta App_Data.
Si no ve el archivo Movies.mdf, haga clic en el botn Mostrar todos los
archivos en la barra de herramientas Explorador de soluciones, haga clic en
el botn Actualizar, a continuacin, expanda la carpetaApp_Data.

Haga doble clic en Movies.mdf para abrir el Explorador de servidores, expanda


la carpeta Tablas para ver la tabla de Pelculas.

37

Haga clic con el la tabla Movie y seleccione Mostrar tabla de datos para ver los
datos que ha creado.

38

Haga clic en la tabla Movies y seleccione Abrir tabla de definicin para


ver la estructura de la tabla que el Cdigo de Entity Framework Code First ha
creado para usted.

39

Observe cmo el esquema de la tabla Movies asigna a la clase movie que cre
anteriormente.
Entity Framework Code First crea automticamente este esquema para usted
basado en su clase Movies.
Cuando
haya
terminado,
cierre
la
conexin
haciendo
clic
derecho MovieDBContext y seleccionando Cerrar conexin. (Si usted no cierra
la conexin, es posible que obtenga un error la prxima vez que se ejecuta el
proyecto).

40

Ahora tiene una base de datos y pginas para visualizar, editar, actualizar y
eliminar datos.

Examinar los mtodos de edicin y vista Edicin

En esta seccin, examinaremos los mtodos de accin Editar generados y


puntos de vista para el controlador de Movie.
Pero primero tendr un corto desvo para que la fecha de lanzamiento se vea
mejor.
Abra el archivo models\Movie.cs y agregue las lneas resaltadas que se
muestran a continuacin:

using System;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;

41

namespace MvcMovie.Models
{
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}",
ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
public class MovieDBContext : DbContext
{
public DbSet<Movie> Movies { get; set; }
}
}

Tambin puede especficar la fecha de esta manera:


[Display(Name = "Release Date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode =
true)]
public DateTime ReleaseDate { get; set; }

El atributo Display especifica lo que desea mostrar el nombre de un campo (en


este caso "Fecha de Lanzamiento" en lugar de"ReleaseDate"). El
atributo DataType especifica el tipo de los datos, en este caso se trata de una
fecha, por lo que la informacin de tiempo almacenada en el campo no se
muestra.
Se necesita el atributo DisplayFormat por un error en el navegador Chrome que
convierte formatos de fecha incorrecta.

42

Ejecutar la aplicacin y busque el controlador Movies. Mantenga el puntero del


ratn sobre el enlace Editar para ver la URL que enlaza.

El enlace Editar fue generada por el mtodo Html.ActionLink en la vista


Views\Movies\Index.cshtml
@Html.ActionLink("Edit", "Edit", new { id=item.ID })

El objeto Html es un ayudante que est expuesta utilizando una propiedad de la


clase base System.Web.Mvc.WebViewPage. El mtodo ActionLink hace que
sea fcil de generar dinmicamente hipervnculos HTML que se enlazan
con mtodos de accin en los controladores. El primer argumento del
mtodo ActionLink es el texto del enlace arender (por
ejemplo, <a> Editar </a>).El segundo argumento es el nombre del mtodo de

43

accin para invocar (En este caso, la accin de edicin). El ltimo


argumento es un objeto annimo que genera los datos de la ruta (en este caso,
el ID de 4).
El enlace
generado se
muestra
en la
imagen
anterior es
http: //localhost: 52947/Movies/Editar/3.
La ruta
por
defecto (establecido
en App_Start\RouteConfig.cs) realiza el patrn de URL {controlador} / {accin} /
{id}.
Por
lo
tanto,
ASP.NET traduce http://localhost:52947/Movies/Editar/3 en
una peticin al mtodo Edit accin del controlador Movies con el ID
de parmetro igual
a
3. Examine
el siguiente
cdigo
del
archivo App_Start\RouteConfig.cs. El mtodo MapRoute se utiliza para las
solicitudes HTTP ruta para el controlador y el mtodo accin y suministrar el
parmetro opcional ID. El mtodo MapRoute tambin es utilizado
por los HtmlHelper tales
como ActionLink para
generar URLs dado el
controlador, el mtodo de accin y los datos de ruta.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index",
id = UrlParameter.Optional }
);
}

Tambin puede pasar parmetros del mtodo de accin utilizandouna cadena


de
consulta.
Por
ejemplo, la
direccin
URL
http://localhost:52497/Movies/EditarID=3
tambin pasa el
parmetro
ID del 3 al mtodo Editar accin del controlador Movies.

44

Abra el controlador Movies. Los dos mtodos de accin Editar se muestran a


continuacin.
// GET: /Movies/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
// POST: /Movies/Edit/5
// To protect from overposting attacks, please enable the specific properties
you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="ID,Title,ReleaseDate,Genre,Price")]
Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");

45

}
return View(movie);
}

Observe el segundo mtodo Edit accin va precedido por el atributoHttpPost.


Este atributo especifica que la sobrecarga del mtodo de edicinse puede
invocar slo para peticiones POST. Se podra aplicar el atributo HttpGet con el
primer mtodo de edicin,pero eso no es necesario porque es el valor
predeterminado. (Nos referimos a los mtodos de accin que se asignan de
forma
implcita al
atributo HttpGet como HTTPGet.) El
atributoBind es
otro mecanismo de seguridad importante que mantiene a los hackers ms de la
colocacin de anuncios de datos a su modelo. Slo debe incluir
propiedades en el
enlace de
atributos que desea
cambiar.
El
atributo ValidateAntiForgeryToken se utiliza para prevenir la falsificacin de una
solicitud y se empareja con Html.AntiForgeryToken () en el archivo de vista de
edicin (Views\Movies\Edit.cshtml). A continuacin se muestra una parte:
@model MvcMovie.Models.Movie
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Movie</h4>
<hr />
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.ID)
<div class="form-group">
@Html.LabelFor(model => model.Title, new { @class = "controllabel col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
</div>

@Html.AntiForgeryToken() genera una forma oculta anti-falsificacin que debe


coincidir en el mtodo Edit del controlador de Movies.

46

El mtodo HttpGet Editar toma el parmetro ID pelcula, busca la pelcula


utilizando Entity Framework. Encuentre el mtodo, y devuelve la pelcula
seleccionada para la vista Editar. Si una pelcula no se puede encontrar, se
devuelve HttpNotFound. Cuando el sistema de scaffolding crea la vista Editar,
examina la clase Movie y crea cdigo para rendir <label> y <input> elementos
para cada propiedad de la clase. El siguiente ejemplo muestra la vista de
edicin generada por el sistema de scaffolding de Visual Studio:
@model MvcMovie.Models.Movie
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Movie</h4>
<hr />
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.ID)
<div class="form-group">
@Html.LabelFor(model => model.Title, new { @class = "controllabel col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ReleaseDate, new { @class =
"control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ReleaseDate)
@Html.ValidationMessageFor(model => model.ReleaseDate)
</div>
</div>
@*Genre and Price removed for brevity.*@
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>

47

}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

Observe cmo la plantilla de vista tiene una declaracin @Model


MvcMovie.Models.MovieModel en la parte superior del archivo - especifica que
la view espera que el modelo de la plantilla de vista sea del tipo Movies.
El cdigo scaffolded utiliza varios mtodos de ayuda para agilizar el formato
HTML. El ayudante Html.LabelFor muestra el nombre del campo ("Ttulo",
"ReleaseDate", "Gnero", o "Precio"). El ayudante Html.EditorFor reproduce una
etiqueta HTML <input>. El ayudante Html.ValidationMessageFor muestra los
mensajes de validacin asociados con esa propiedad.
Ejecute la aplicacin y agregue en la URL /Movies. Haga click en el enladie
Editar. En el navegador, haga click derecho y selecciones ver el cdigo
fuente de la pgina. El cdigo HTML para el elemento de formulario se muestra
a continuacin.
<form action="/movies/Edit/4" method="post">
<input name="__RequestVerificationToken" type="hidden"
value="UxY6bkQyJCXO3Kn5AXg6TXxOj6yVBi9tghHaQ5Lq_qwKvcojNXEEfcbnFGh_0vuw4tS_BRk7QQQHlJp8AP4_X4orVNoQnp2cd8kXhykS01" /> <fieldset
class="form-horizontal">
<legend>Movie</legend>
<input data-val="true" data-val-number="The field ID must be a
number." data-val-required="The ID field is required." id="ID" name="ID"
type="hidden" value="4" />
<div class="control-group">
<label class="control-label" for="Title">Title</label>
<div class="controls">
<input class="text-box single-line" id="Title" name="Title"
type="text" value="GhostBusters" />
<span class="field-validation-valid help-inline" data-valmsgfor="Title" data-valmsg-replace="true"></span>
</div>
</div>
<div class="control-group">

48

<label class="control-label" for="ReleaseDate">Release Date</label>


<div class="controls">
<input class="text-box single-line" data-val="true" data-valdate="The field Release Date must be a date." data-val-required="The
Release Date field is required." id="ReleaseDate" name="ReleaseDate"
type="date" value="1/1/1984" />
<span class="field-validation-valid help-inline" data-valmsgfor="ReleaseDate" data-valmsg-replace="true"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="Genre">Genre</label>
<div class="controls">
<input class="text-box single-line" id="Genre" name="Genre"
type="text" value="Comedy" />
<span class="field-validation-valid help-inline" data-valmsgfor="Genre" data-valmsg-replace="true"></span>
</div>
</div>
<div class="control-group">
<label class="control-label" for="Price">Price</label>
<div class="controls">
<input class="text-box single-line" data-val="true" data-valnumber="The field Price must be a number." data-val-required="The Price
field is required." id="Price" name="Price" type="text" value="7.99" />
<span class="field-validation-valid help-inline" data-valmsgfor="Price" data-valmsg-replace="true"></span>
</div>
</div>
<div class="form-actions no-color">
<input type="submit" value="Save" class="btn" />
</div>
</fieldset>
</form>

Los elementos <input> se encuentran en una etiqueta <form>elemento


cuyo atributo action establece publicar en la URL /Movies/Editar. Los datos del
formulario se publicarn en el servidor cuando se hace clic en el botn Guardar.
La
segunda
lnea
muestra el
token XSRF oculto generado
por la
llamada @Html.AntiForgeryToken().

49

El procesamiento de la Peticin POST


El siguiente listado muestra la versin HttpPost del mtodo Edit accin.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="ID,Title,ReleaseDate,Genre,Price")]
Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}

El atributo ValidateAntiForgeryToken valida el token XSRF generado por la


llamada @Html.AntiForgeryToken() en la vista.
El modelo ASP.NET MVC toma los valores a un formulario y crea un objeto
Movie que
pasa como
parmetro
la
pelcula.
El
mtodo ModelState.IsValid verifica que los datos presentados en la forma se
pueden utilizar para modificar (editar o actualizar) un objeto Movie. Si los datos
son vlidos, los datos de Movie se guarda en la coleccin de Movies de la db (instancia
MovieDBContext). Los nuevos datos de la pelcula se guardan en la base de
datos llamando al mtodo SaveChanges de MovieDBContext. Despus de
guardar los datos, el cdigo redirige al usuario al mtodo de accin Index de la
clase MoviesController,
que
muestra
la
coleccin
de
pelculas, incluyendo los cambios que acaba de hacer.
Tan pronto como la validacin del lado del cliente determina que valores de un
campo no
son
vlidos,
se
muestra un
mensaje
de
error.
Si
deshabilita JavaScript, usted no tendr validacin del lado del cliente, pero el
servidor detectar que los valores publicados no son vlidos, y en los valores
del formulario se vuelven a mostrar los mensajes de error.
El ayudante Html.ValidationMessageFor en las plantilla de vista Edit.cshtml se
encarga de mostrar los mensajes de error correspondientes.

50

Todos los mtodos HTTPGet siguen un patrn similar. Consiguen un objeto de


pelcula (o lista de objetos, en el caso del index), y pasan el modelo a la vista.
El mtodo Create pasa un objeto de pelcula vaco a la vista Crear.
Los mtodos crear, editar, borrar o modificar los datos lo hacen en los mtodos
de sobrecarga HttpPost. La Modificacin de datos en un mtodo HTTP GET
es un riesgo de seguridad, tal como se describe en la entrada
de blog MVCASP.NET Tip # 46 - No utilice enlace Delete porque crean agujeros
de seguridad. La Modificacin de datos en un mtodo GET HTTP tambin
viola las mejores prcticas y el patrn de arquitectura REST, que especifica
que las peticiones GET no deberan cambiar el estado de su solicitud. En otras
palabras, la realizacin de una operacin GET debe ser una operacin
segura que no tiene efectos secundarios y no modifica sus datos persistido.
Si est utilizando una computadora de EE.UU.-Ingls, puede saltarse esta seccin
y vaya a la siguiente tutorial.
1. Desde el Herramientas men, haga clic en Administrador de
paquetes NuGet y, a continuacin, haga clic enAdministrar paquetes
NuGet para solucin.

51

2. En el panel izquierdo, seleccione En lnea. (Ver la imagen de abajo.)


3. En el cuadro bsqueda de paquetes Instalado introduzca Globalize.
4. Haga clic en Instalar. Los archivos Scripts\jquery.globalize\globalize.js se
aadirn a su proyecto. La carpeta Scripts\jquery.globalize\culture\
contendrn muchos archivos JavaScript culture. Tenga en cuenta, puede
tomar cinco minutos para instalar este paquete.

52

El
siguiente
cdigo
Views\Movies\Edit.cshtml:

muestra

las

modificaciones

al

archivo

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script src="~/Scripts/globalize/globalize.js"></script>
<script
src="~/Scripts/globalize/cultures/globalize.culture.@(System.Threading.Thre
ad.CurrentThread.CurrentCulture.Name).js"></script>
<script>
$.validator.methods.number = function (value, element) {
return this.optional(element) ||
!isNaN(Globalize.parseFloat(value));
}
$(document).ready(function () {
Globalize.culture('@(System.Threading.Thread.CurrentThread.CurrentCultur
e.Name)');
});
</script>
<script>
jQuery.extend(jQuery.validator.methods, {
range: function (value, element, param) {

53

//Use the Globalization plugin to parse the value


var val = Globalize.parseFloat(value);
return this.optional(element) || (
val >= param[0] && val <= param[1]);
}
});
$.validator.methods.date = function (value, element) {
return this.optional(element) ||
Globalize.parseDate(value) ||
Globalize.parseDate(value, "yyyy-MM-dd");
}
</script>
}

Para evitar la repeticin de este cdigo en todas las vistas de edicin,


puede moverlo al archivo de diseo.
Como solucin temporal, si usted no puede conseguir trabajo de validacin en
su localidad, puede forzar el equipo para utilizar ingles estadounidenses o
puede desactivar JavaScript en su navegador. Para forzar el equipo para
utilizar EE.UU. Ingls, usted puede agregar el elemento de la globalizacin en
el archivo raz del proyecto web.config. El siguiente cdigo muestra el elemento
de la globalizacin de la cultura establecida en Estados Unidos Ingls.
<system.web>
<globalization culture ="en-US" />
<!--elements removed for clarity-->
</system.web>

Search (Bsqueda)
Adicin de un mtodo Search y de Views Search
En esta seccin, agregar capacidad de bsqueda para el mtodo
accin Index que le permite buscar pelculas por gnero o nombre.

de

Actualizacin del formulario de Index


Comience por la actualizacin del mtodo de accin Index de la clase
MoviesController existente. Aqu se muestra el cdigo:
public ActionResult Index(string searchString)
{

54

var movies = from m in db.Movies


select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}

La primera lnea del mtodo Index crea la


seleccionar las pelculas:

consulta followingLINQ

para

var movies = from m in db.Movies


select m;

La consulta se define en este punto, pero an no se ha ejecutado en contra de


la base de datos.
Si el parmetro searchstring contiene una cadena, la consulta de peliculas se
modifica para filtrar en el valor de la cadena de bsqueda, usando el siguiente
cdigo:
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}

El cdigo s => s.title anterior es una expresin lambda. Lambdas se utilizan en


mtodos basados en consultas LINQ como argumentos a mtodos
estndar operador de consulta tales como el mtodo en el que se utiliza en el
cdigo anterior. Las consultas LINQ no se ejecutan cuando se definen o cuando
se modifican llamando a un mtodo como WHERE o OrderBy. En su lugar, la
ejecucin de consultas se difiere, lo que significa que la evaluacin de una
expresin se retrasa hasta su valor realizado en realidad repiten a lo largo o se
llama al mtodo ToList. En la muestra de bsqueda, la consulta se ejecuta en la
vista Index.cshtml. Nota: El mtodo Contains ejecuta en la base de datos, no
el cdigo c # anteriormente. La base de datos, Contiene mapas a SQL LIKE,
que es sensible a maysculas.
Ahora usted puede actualizar la vista de ndice que mostrar el formulario al
usuario.
Ejecute la aplicacin y vaya a /Movies/Index. Anexar una cadena de
consulta como
?searchString=ghost
para
el
URL.
Se
muestran
las pelculas filtradas.

55

Si cambiar la firma del mtodo Index debe tener un parmetro llamado id, el
parmetro id coincidir con el {id} marcador de posicin para las rutas por
defecto establecidos en el archivo App_Start\RouteConfig.cs.
{ controller } / { accin } / { ID }

El mtodo Index original se parece a esto:


public ActionResult Index(string searchString)
{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}

El mtodo Index modificado se vera de la siguiente manera:


public ActionResult Index(string id)
{
string searchString = id;
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}

Ahora puede pasar el titulo de bsqueda como datos de la ruta (un


segmento URL) en lugar de como un valor de cadena de consulta.
Sin embargo, no se puede esperar que los usuarios modifiquen la direccin
URL cada vez que quieren buscar una pelcula. As que ahora vamos a
aadir la interfaz de usuario para ayudarles a filtrar pelculas. Si ha cambiado
la firma del mtodo Index para probar cmo pasar el parmetro ID como

56

ruta determinada, cambie de nuevo para que


un parmetro de cadena denominado searchstring:

su mtodo

de Index

tome

public ActionResult Index(string searchString)


{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}

Abra
el
archivo Views\Movies\Index.cshtml, y
justo
despus
de @Html.ActionLink ("Crear nuevo", "Crear"), aadir la forma de marcas que se
destacan a continuacin:
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm()){
<p> Title: @Html.TextBox("SearchString") <br />
<input type="submit" value="Filter" /></p>
}
</p>
El ayudante
Html. BeginForm crea
una
apertura <form>.El
ayudante Html.BeginForm causa la forma de enviar a s mismo cuando el usuario
enva el formulario haciendo clic en el botn Filtro.
Visual Studio 2013 tiene una buena mejora en la visualizacin y edicin de Ver
archivos.
Al
ejecutar la
aplicacin
con
una vista
abierta archivo, Visual
Studio2013 invoca el mtodo de accin del controlador correcto para mostrar la vista.

57

Con el archivo Index de View abierto en Visual Studio (como se muestra en la imagen
de arriba), toque Ctr F5 o F5 para ejecutar la aplicacin y luego intentar la bsqueda
de una pelcula.
No hay sobrecarga HttpPost del mtodo Index. Usted no lo necesita, porque el
mtodo no cambia el estado de la aplicacin, el filtrado de datos.
Se podra aadir el siguiente mtodo HttpPost Index. En ese caso, el invocador accin
podra coincidir
con
el
mtodo
HttpPost Index, y
el
mtodo HttpPost ndice correra como se muestra en la imagen de abajo.
[HttpPost]
public string Index(FormCollection fc, string searchString)
{
return "<h3> From [HttpPost]Index: " + searchString + "</h3>";
}

Sin embargo, incluso si se agrega esta versin del metodo HttpPostIndex, hay
una limitacin en la forma en que todo esto ha sido implementado. Imagine que
usted desea marcar una bsqueda particular o desea enviar un enlace a tus
amigos que pueden hacer clic con el fin de ver la misma lista filtrada de pelculas.
Observe que la direccin URL de la solicitud HTTP POST es la misma que la direccin
URL de la solicitud GET (localhost: xxxxx/Movies/Index) - no hay informacin de
bsqueda en la propia direccin URL. En este momento, la informacin de la

58

cadena de bsqueda se enva al servidor como un valor de campo de formulario.


Esto significa que no puede capturar esa informacin de bsqueda demarcador
o enviar a los amigos en una URL.
La solucin es utilizar una sobrecarga de BeginForm que especifica que la peticin
POST debe aadir la informacin de bsqueda de la URL y que debe ser enviado
a la HttpGet versin del mtodo Index. Reemplace el mtodo BeginForm sin
parmetros existente con el siguiente cdigo:
@using (Html.BeginForm("Index","Movies",FormMethod.Get))
Ahora, cuando usted enva una bsqueda, la URL contiene una cadena de consulta
de bsqueda. La bsqueda tambin ir al mtodo de accin HttpGet Index, incluso si
usted tiene un mtodo HttpPost Index.

Agregar bsqueda por gnero


Si ha aadido la versin HttpPost del mtodo Index, borrarlos ahora.
A continuacin, vamos a aadir una funcin para permitir a los usuarios buscar
pelculas por gnero. Reemplace el mtodo Index con el siguiente cdigo:
public ActionResult Index(string movieGenre, string searchString)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());

59

ViewBag.movieGenre = new SelectList(GenreLst);


var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
return View(movies);
}

Esta versin del mtodo Index toma un parmetro adicional nombrado movieGenre.
Las primeras lneas de cdigo crean un objeto de lista para celebrar gneros
cinematogrficos, desde la base de datos.
El cdigo siguiente es una consulta LINQ que recupera todos los gneros, desde la
base de datos.
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;

El cdigo utiliza el mtodo AddRange de la coleccin de lista genrica para aadir


todos los gneros distintos a
la
lista.
(Sin
el modificador Distinto, se
aadiran gneros duplicados - por ejemplo, se aadira la comedia en dos ocasiones
en nuestra muestra). El cdigo a continuacin, almacena la lista de gneros en el
objeto ViewBag.movieGenre. Almacenamiento de datos de categora (de un gnero de
pelculas) como un objeto SelectList en un ViewBag, a continuacin, acceder a
los datos de categora en un cuadro de lista desplegable es un enfoque tpico
para aplicaciones MVC.
El siguiente cdigo muestra cmo comprobar el parmetro movieGenre. Si no est
vaco,
el
cdigo restringe an
ms
las pelculas
de
consulta
para
limitar las pelculas seleccionadas para el gnero especificado.
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}

60

Como se dijo anteriormente, la consulta no se ejecuta en la base de datos hasta que


la lista de pelculas se repite a lo largo (que ocurre en la vista, despus del
mtodo indexAction devoluciones).

Agregar marcado del Index Views para Buscar por Gnero


Aadir un
TextBox.

Html.DropDownList al

archivo Views\Movies\Index.cshtml, antes

del

@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm("Index", "Movies", FormMethod.Get))
{
<p>
Genre: @Html.DropDownList("movieGenre", "All")
Title: @Html.TextBox("SearchString")
<input type="submit" value="Filter" />
</p>
}
</p>
<table class="table">
En el siguiente cdigo:
@Html.DropDownList("movieGenre", "All")
El parmetro "movieGenre" proporciona la clave para el ayudante DropDownList para
encontrar un IEnumerable <SelectListItem> en
el
ViewBag.
El ViewBag fue
poblada en el mtodo de accin:
public ActionResult Index(string movieGenre, string searchString)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);

61

var movies = from m in db.Movies


select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
return View(movies);
}

El parmetro "All" proporciona el elemento de la lista para ser preseleccionado. Si


hubiramos usado el siguiente cdigo:
@Html.DropDownList("movieGenre", "Comedy")
Y tuviramos una pelcula con un gnero "Comedia" en nuestra base de
datos, "Comedia" sera preseleccionado en la lista desplegable. Porque no
tenemos un gnero de la pelcula "All", no hay "All" en SelectList, as que cuando
nos fijamos de nuevo sin hacer un selection, el valor de cadena de
consulta movieGenre est vaca.
Ejecute la aplicacin y vaya a /Movies/Index. Intente
gnero, por nombre de la pelcula, y por ambos criterios.

62

una

bsqueda por

En esta seccin se ha creado un mtodo de accin de bsqueda y


vista que permiten a los usuarios buscar por ttulo de la pelcula y el gnero.

la

Adicin de un nuevo campo


En esta seccin vamos a usar Entity Framework Code First migraciones para
migrar algunos cambios en las clases del modelo de manera que se aplique el cambio
en la base de datos.
Por defecto, se utiliza Entity Framework Code First para crear automticamente una
base de datos, como lo hizo anteriormente en este tutorial, Code First agrega una
tabla a la base de datos para ayudar a rastrear si el esquema de la base de datos est
en sintona con el modelo de clases que fue generada. Si no estn en sincrona, Entity
Framework genera un error. Esto hace que sea ms fcil de localizar problemas en el
tiempo de desarrollo que de otro modo slo podra encontrar (por errores oscuros) en
tiempo de ejecucin.

Configuracin Code First Migrations para cambios en el modelo


Vaya al Explorador de soluciones. Haga clic derecho sobre el archivo y seleccione
Eliminar Movies.mdf para eliminar la base de datos de pelculas. Si no ve el
archivo Movies.mdf, haga clic en el icono de Mostrar todos los archivos

63

Genere la aplicacin para asegurarse de que no hay errores.


Desde el men Herramientas, haga clic en Administrador de paquetes NuGet y
luego consola del Administrador de paquetes.

En la ventana de la consola del Administrador de paquetes en el PM> teclee


Enable-Migraciones -ContextTypeName MvcMovie.Models.MovieDBContext

64

El
comando Enable-Migraciones (ver
imagen
superior) crea
archivo Configuration.cs en una nueva carpeta de Migraciones.

un

Visual Studio abre el archivo Configuration.cs. Reemplace el mtodo Seed en el


archivo Configuration.cs con el siguiente cdigo:
protected override void Seed(MvcMovie.Models.MovieDBContext context)
{
context.Movies.AddOrUpdate( i => i.Title,
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-1-11"),
Genre = "Romantic Comedy",
Price = 7.99M
},

65

new Movie
{
Title = "Ghostbusters ",
ReleaseDate = DateTime.Parse("1984-3-13"),
Genre = "Comedy",
Price = 8.99M
},
new Movie
{
Title = "Ghostbusters 2",
ReleaseDate = DateTime.Parse("1986-2-23"),
Genre = "Comedy",
Price = 9.99M
},
new Movie
{
Title = "Rio Bravo",
ReleaseDate = DateTime.Parse("1959-4-15"),
Genre = "Western",
Price = 3.99M
}
);
}

Haga clic derecho sobre la lnea roja ondulada bajo Movie y


luego haga clic en usingMvcMovie.Models;

66

selectResolve y

Si lo hace, aade la siguiente instruccin using:


using MvcMovie.Models;

Presione CTRL-SHIFT-B para construir el proyecto. (Los siguientes pasos se producir


un error si no construir en este punto.)
El siguiente paso es crear una clase DbMigration para la migracin inicial. Esta
migracin crea una nueva base de datos, es por eso que ha borrado el
archivo movie.mdf en un paso anterior.
En la ventana de la consola del Administrador de paquetes, ingrese el comando addmigration Initial para crear la migracin inicial. El nombre "initial" es arbitrario y se
utiliza para nombrar el archivo de migracin creado.

Code First Migration crea otro archivo de clase en la carpeta de Migraciones (con el
nombre {DateStamp} _Initial.cs), y esta clase contiene cdigo que crea el esquema
de base de datos. El nombre del archivo de migracin est pre-fijada con una marca
de tiempo para ayudar con el pedido. Examine el archivo {DateStamp} _Initial.cs, que
contiene las instrucciones para crear la tabla Pelculas para la pelcula DB. Al
actualizar la base de datos en las instrucciones a continuacin, este
archivo {DateStamp} _Initial.cs se ejecutar y creara el esquema de base de datos.
A continuacin, el mtodo de Seed correr a poblar la DB con los datos de prueba.
En la consola del Administrador de paquetes, tipee el comando update-database para crear la
base de datos y ejecutar el mtodo Seed
.

67

Si recibe un error que indica una tabla ya existe y no se puede crear, es


probablemente porque se le termin la aplicacin despus de que ha eliminado la
base de datos y antes de ejecutar update-database. En ese caso, elimine el
archivo Movies.mdf de nuevo y vuelva a intentar el comando update-database. Si
contina recibiendo un error, elimine la carpeta migraciones y contenido a
continuacin, iniciar con las instrucciones en la parte superior de esta
pgina (es borrar el archivo Movies.mdf luego proceder a Enable-Migraciones).
Ejecute la aplicacin y vaya a la URL /Movies. Se muestran los datos del Seed.

Adicin de una Clasificacin de la Propiedad al Modelo Pelicula


Comience por agregar una nueva propiedad de Calificacin a la clase Movie existente.
Abra el archivo models\Movie.cs y aada la propiedad Rating como ste:
public string Rating { get; set; }
La clase completa de Movie ahora se ve como el siguiente cdigo:
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]

68

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}",
ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
public string Rating { get; set; }
}

Generar la aplicacin (Ctrl + Shift + B).


Debido a que ha aadido un nuevo campo a la clase de Movie, tambin es
necesario actualizar la lista blanca de la unin por lo que esta nueva propiedad ser
incluida. Actualice el atributo bind para Crear y el mtodo de accin de edicin para
incluir la propiedad Rating:
[Bind(Include = "ID,Title,ReleaseDate,Genre,Price,Rating")]
Tambin es necesario actualizar las plantillas de vista con el fin de visualizar, crear y
editar la nueva propiedad Rating en la vista del navegador.
Abra el archivo \Viewa\Movies\Index.cshtml y aada un <th>Rating</ th> encabezado
de columna justo despus de la columna Precio. A continuacin, agregue un elemento
columna <td> cerca del final de la plantilla para tener el valor@item.Rating. A
continuacin se muestra la plantilla de vista Index.cshtml actualizada:
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm("Index", "Movies", FormMethod.Get))
{
<p>
Genre: @Html.DropDownList("movieGenre", "All")
Title: @Html.TextBox("SearchString")
<input type="submit" value="Filter" />
</p>
}
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Title)
</th>
<th>
@Html.DisplayNameFor(model => model.ReleaseDate)

69

</th>
<th>
@Html.DisplayNameFor(model => model.Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Rating)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem
</td>
<td>
@Html.DisplayFor(modelItem
</td>
<td>
@Html.DisplayFor(modelItem
</td>
<td>
@Html.DisplayFor(modelItem
</td>
<td>
@Html.DisplayFor(modelItem
</td>

=> item.Title)

=> item.ReleaseDate)

=> item.Genre)

=> item.Price)

=> item.Rating)

<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>
}
</table>

A continuacin, abra la carpeta \Views\Movies\Create.cshtml y agregue el


campo Clasificacin con el siguiente marcado highlighed. Esto hace que un cuadro de
texto pueda especificar una clasificacin cuando se crea una nueva pelcula.

70

<div class="form-group">
@Html.LabelFor(model => model.Price, new { @class = "control-label colmd-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Price)
@Html.ValidationMessageFor(model => model.Price)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Rating, new { @class = "control-label colmd-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Rating)
@Html.ValidationMessageFor(model => model.Rating)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

Ahora usted ha informado el cdigo


propiedad de Calificacin.

de

la

aplicacin para

apoyar la

nueva

Ejecute la aplicacin y vaya a la URL /Movies. Al hacer esto, sin embargo, ver uno de

los siguientes errores:

71

El modelo de respaldo al contexto 'MovieDBContext' ha cambiado desde que se


cre la base de datos. Considere el uso de Code First Migrations de actualizar la base
de datos (http://go.microsoft.com/fwlink/?LinkId=238269).

72

Ests viendo este error porque la clase del modelo Movie actualizadoen la
aplicacin es ahora diferente que el esquema de la tabla de la pelcula de la base de
datos existente. (No hay columna de Clasificacin en la tabla de base de datos.).
Actualizar el mtodo de Seed de modo que proporcione un valor para la nueva
columna. Abrir el archivo Migrations\Configuration.cs y agregue un campo Rating
a cada objeto de pelcula.
new Movie
{
Title = "When Harry Met Sally",
ReleaseDate = DateTime.Parse("1989-1-11"),
Genre = "Romantic Comedy",
Rating = "PG",
Price = 7.99M
},

Construir la solucin, y luego abra la ventana de la consola del Administrador de


paquetes e introduzca el siguiente comando: add-migration Rating
El comando add-migracin cuenta la infraestructura de migracin para examinar el
modelo actual de la pelcula con el esquema MovieDB actual y crear el cdigo
necesario para migrar la base de datos para el nuevo modelo. El nombre Rating
es arbitrario y se utiliza para nombrar el archivo de migracin. Es til usar un nombre
significativo para el paso de migracin.
Cuando este comando finalice, Visual Studio abre el archivo de clase que define la
nueva clase DbMIgration derivados, y en el mtodo de arriba se puede ver el cdigo
que crea la nueva columna.
public partial class AddRatingMig : DbMigration
{
public override void Up()
{
AddColumn("dbo.Movies", "Rating", c => c.String());
}
public override void Down()
{
DropColumn("dbo.Movies", "Rating");
}
}

Construir la solucin, y luego ingresar update-database del sistema en la consola


del Administrador de paquetes ventana.
La siguiente imagen muestra el resultado en la ventana de la consola del
Administrador de paquetes (La fecha del sello prepending Rating ser diferente.)

73

Vuelva a ejecutar la aplicacin y vaya a la URL /Movies

Haga clic en el enlace crear nuevo para agregar una nueva pelcula. Tenga en cuenta
que usted puede aadir una calificacin.

74

Haga click en Crear. La nueva pelcula, incluida la clasificacin, ahora aparece en las
pelculas del anuncio:
Ahora que el proyecto es el uso de las migraciones, usted no tendr que dejar la base
de datos cuando se agrega un nuevo campo o actualizar de otra manera el esquema.
Tambin debe agregar el campo Rating a la edicin, Detalles Borrar plantillas de vista.

Puede introducir el comando "update-database" en la ventana de la consola del


Administrador de paquetes nuevo y sin cdigo demigracin tendra que
ejecutar, porque el esquema coincide con el modelo. Sin embargo, ejecutar "updatedatabase" se ejecutar el mtodo de Seed de nuevo, y si ha cambiado alguno de los
datos del Seed, los cambios se perdern porque los datos del mtodo de
Seed upserts.
En esta seccin usted vio cmo se pueden modificar los objetos del
modelo y mantener la base de datos en sincrona con los cambios. Tambin ha
aprendido una manera de rellenar una base de datos recin creada con datos de la
muestra para que pueda probar escenarios.

75

Adicin de Validacin
En esta seccin vamos a aadir lgica de validacin para el modelo Movies, y se
asegurar de que las reglas de validacin se aplican cada vez que un usuario
intenta crear o editar una pelcula utilizando la aplicacin.

Mantener Cosas DRY


Uno de los principios fundamentales de diseo de ASP.NET MVC es DRY ("Do
not Repeat Yourself"). ASP.NET MVC le estimula para especificar la funcionalidad o
comportamiento slo una vez, y luego tienen que reflejarse en todas partes en una
aplicacin. Esto reduce la cantidad de cdigo que necesita para escribir y hace que
el cdigo que escribes sea menos propenso a errores y fcil de mantener.
El apoyo proporcionado por la validacin ASP.NET MVC y Entity Framework Code
Firstes son un gran ejemplo del principio DRY en accin. Puede especificar de forma
declarativa reglas de validacin en un solo lugar (en la clase del modelo) y las
normas se aplican en todas partes en la aplicacin.
Echemos un vistazo a cmo usted puede tomar ventaja de este soporte de validacin en la
aplicacin de la pelcula.

Adicin de reglas de validacin para el modelo Movie


Vamos a empezar aadiendo un poco de lgica de validacin a la clase Movie.
Abra
el
archivo Movie.cs.
Observe
el espacio
de
nombresSystem.ComponentModel.DataAnnotations no
contiene
System.Web.
DataAnnotations proporciona un conjunto integrado de validacin de atributos que se
pueden aplicar de forma declarativa de cualquier clase o propiedad (Tambin
contiene atributos de formato como el tipo de datos que ayudan con el formato y que
no ofrecen ningn tipo de validacin.).
Ahora actualizar la clase de Movie para tomar ventaja de la incorporada
en Obligatorio, StringLength, RegularExpression y atributos de validacin de rango.
Vuelva a colocar la clase de pelcula con lo siguiente:
public class Movie
{
public int ID { get; set; }

[StringLength(60, MinimumLength = 3)]


public string Title { get; set; }

76

[Display(Name = "Release Date")]


[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}",
ApplyFormatInEditMode = true)]
public DateTime ReleaseDate { get; set; }

[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]
[Required]
[StringLength(30)]
public string Genre { get; set; }

[Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }

[RegularExpression(@"^[A-Z]+[a-zA-Z''-'\s]*$")]
[StringLength(5)]
public string Rating { get; set; }
}
El atributo StringLength establece la longitud mxima de la cadena, y establece esta
limitacin en la base de datos, por lo tanto, el esquema de base de datos va a
cambiar. Haga clic en la tabla Movies en el Explorador de servidores y haga clic en
Abrir tabla de definicin

77

:
En la imagen superior, se puede ver todos los campos de cadena se establecen en
NVARCHAR (MAX). Vamos a utilizar las migraciones para actualizar el esquema.
Construir la solucin, y luego abrir la consola del Administrador de paquetes ventana
e introduzca los siguientes comandos:
add-migration DataAnnotations
update-database
Cuando estos comandos terminen, Visual Studio abre el archivo de clase que define la
nueva DbMIgration clase derivada con el nombre especificado (DataAnnotations), y en
el mtodo de arriba se puede ver el cdigo que actualiza las restricciones de
esquema:
public override void Up()
{
AlterColumn("dbo.Movies", "Title", c => c.String(maxLength: 60));
AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false, maxLength:
30));
AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5));
}

El campo de Gnero ya no son anulable (es decir, se debe introducir un valor). El


campo Rating tiene una longitud mxima de 5 y Title tiene una longitud mxima de 60.

78

La longitud mnima de 3 en el Ttulo y el rango de precio no cre los cambios de


esquema
Examinar el esquema de la pelcula:

Los campos de cadena muestran los nuevos lmites de longitud y Gnero ya no est
marcada como anulable.
Los atributos de
modelo que se

validacin especifican el comportamiento que desea aplicar a las del


aplican. Los atributos Required y MinimumLength indican que

una propiedad debe tener un valor; pero nada impide que un usuario entrar en el
espacio blanco para satisfacer esta validacin. El atributo RegularExpression se utiliza
para limitar lo que los personajes se pueden introducir. En el cdigo anterior, Gnero y
clasificacin deben utilizar slo letras (espacios en blanco, nmeros y caracteres
especiales no estn permitidos). El atributo Range limita a un valor dentro de un rango
especificado. El atributo StringLength le permite ajustar la longitud mxima de una
propiedad de cadena y, opcionalmente, su longitud mnima. Los tipos de
valor (como decimal, int, float, DateTime) son inherentemente necesarios y no
necesitan el atributo Required.
Code First asegura que las reglas de validacin que especifique en una clase del
modelo se aplican antes de que la aplicacin guarde los cambios en la base de datos.
Por
ejemplo, el
cdigo
de
abajo arrojar una excepcinDbEntityValidationException cuando se llama al mtodo
SaveChanges, debido a que varios valores de propiedad de pelcula requerida faltan:
MovieDBContext db = new MovieDBContext();
Movie movie = new Movie();
movie.Title = "Gone with the Wind";
db.Movies.Add(movie);
db.SaveChanges();
// <= Will throw server side validation exception

El cdigo anterior arroja la siguiente excepcin:


Error de validacin de una o ms entidades.Ver propiedades. 'EntityValidationErrors'
para mas detalles.

79

Tener reglas de validacin forzadas automticamente por el .NET Framework ayuda a


hacer su aplicacin ms robusta. Tambin asegura que no se puede olvidar de
validar algo y sin querer dejar malos datos en la base de datos.

Error de validacin de IU en ASP.NET MVC


Ejecute la aplicacin y vaya a la URL /Movies.
Haga clic en el enlace crear nuevo para agregar una nueva pelcula. Rellene
el formulario con algunos valores no vlidos. Tan pronto como la validacin del lado
del cliente jQuery detecta el error, se muestra un mensaje de error.

Observe cmo la forma se ha utilizado de forma automtica un color de


borde rojo para destacar los cuadros de texto que contienen datos no vlidos y
ha emitido un mensaje de error de validacin apropiad oal lado de cada uno.
Los errores se aplican tanto del lado del cliente (usando JavaScript y jQuery) como del
lado del servidor (en caso de que un usuario tenga JavaScript desactivado).
Un beneficio real es que usted no necesita cambiar una sola lnea de cdigo de la
clase MoviesController o en la vista Create.cshtml a fin de que esta interfaz de usuario de
validacin. El controlador y puntos de vista que cre anteriormente en este

tutorial recogidos automticamente las


reglas
de
validacin que
ha
especificado mediante el uso de la validacin de atributos en las propiedades de la

80

clase del modelo de la pelcula. Validacin de la prueba utilizando el mtodo de accin


Edit, y se aplica la misma validacin.
Los datos del formulario no se envan al servidor hasta que no haya errores de
validacin del lado del cliente. Usted puede verificar esto poniendo un punto de
quiebre en el mtodo HTTP POST, mediante el uso de la herramienta de fiddler,o las
herramientas de desarrollo F12 IE.

Cmo se produce la validacin en el Crear Vista y mtodo de accin Crear?


Usted
podra
preguntarse cmo
se
gener
la interfaz
de
usuario de
validacin sin cambios en el cdigo del controlador o vistas. La siguiente lista muestra
el mtodo Create de la clase MovieController. Son sin cambios desde cmo los
cre anteriormente en este tutorial.
public ActionResult Create()
{
return View();
}
// POST: /Movies/Create
// To protect from overposting attacks, please enable the specific properties
you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include =
"ID,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
if (ModelState.IsValid)
{
db.Movies.Add(movie);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
El primer mtodo de accin (HTTP GET) Crear muestra el formulario initialCreate. La
segunda
versin ([HttpPost])
maneja el
formulario
posterior.
El segundo
mtodo Create (La versin HttpPost) llama ModelState.IsValid para comprobar si
la pelcula tiene algn error de validacin. La llamada a este mtodo evala los
atributos de validacin que se han aplicado al objeto. Si el objeto tiene errores de
validacin, el mtodo vuelve a mostrar el formulario Create. Si no hay errores, el
mtodo guarda la nueva pelcula en la base de datos. En nuestro ejemplo de la
pelcula, el formulario no se ha publicado en el servidor cuando hay errores de
validacin detectados en el lado del cliente; el segundo mtodo Create nunca se
llama. Si desactiva JavaScript en su navegador, la validacin del cliente est

81

desactivada y el mtodo HTTP POST Create llama


comprobar si la pelcula tiene algn error de validacin.

ModelState.IsValid para

Se puede establecer un punto de quiebre en elmetodo HttpPost Create y verificar que


el mtodo nunca se llama, la validacin del lado del cliente no presentar los datos del
formulario cuando se detectan errores de validacin. Si desactiva JavaScript en su
navegador, a continuacin, enviar el formulario con errores, el punto de quiebre se
ver afectada. Seguir disfrutando de validacin completa sin JavaScript. La siguiente
imagen muestra cmo deshabilitar JavaScript en Internet Explorer.

82

La siguiente imagen muestra cmo desactivar JavaScript en el navegador FireFox.

La siguiente imagen muestra cmo desactivar JavaScript en el navegador Chrome.

83

A
continuacin
se
muestra la plantilla
de
vista Create.cshtml de
scaffolded anteriormente. Es usado por los mtodos de accin que se muestran
arriba tanto para mostrar la forma inicial y para volver a mostrar en caso de un error.
@model MvcMovie.Models.Movie
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Movie</h4>
<hr />
@Html.ValidationSummary(true)

84

<div class="form-group">
@Html.LabelFor(model => model.Title, new { @class = "controllabel col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div>
</div>
@*Fields removed for brevity.*@

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Observe cmo el cdigo utiliza un ayudante Html.EditorFor para emitir el elemento
<input> para cada caracterstica de la pelcula. Al lado de esta ayuda es una llamada
al mtodo de ayudaHtml.ValidationMessageFor. Estos dos mtodos de ayuda trabajan
con el objeto de modelo que ha pasado por el controlador a la vista (en este caso, un
objeto Pelcula). Se ven de forma automtica para los atributos de validacin
especificadas en los mensajes de error de modelo y de visualizacin, segn proceda.
Lo que es realmente bueno de este enfoque es que ni el controlador ni la plantilla
de vista Create sabe nada acerca de las reglas de validacin reales estn
aplicando o sobre los mensajes de error especficos mostrados. Las reglas de
validacin y las cadenas de error se especifican slo en la clase Movies. Estas
mismas reglas de validacin se aplican automticamente a la vista de edicin y
cualquier otro visitas plantillas puede crear para editar su modelo.
Si desea cambiar la lgica de validacin posterior, puede hacerlo exactamente en
un lugar mediante la adicin de validacin atributos al modelo (en este ejemplo, la
clase de pelcula). Usted no tendr que preocuparse acerca de las diferentes partes
de la aplicacin es incompatible con el modo en que se aplican las reglas - toda la
lgica de validacin se define en un solo lugar y se utiliza en todas partes. Esto

85

mantiene el cdigo muy limpio, y hace que sea fcil de mantener y evolucionar. Y
significa que que podrs honrar plenamente el principio DRY.

Utilizando atributos DataType


Abra el archivo Movie.cs y examinar la clase Movies. El namespace provee atributos
de formato System.ComponentModel.DataAnnotationsofrece, adems de la
incorporada en el conjunto de atributos de validacin. Ya hemos aplicado un valor de
enumeracin DataType a la fecha de lanzamiento y de los campos de precio. El
cdigo siguiente muestra las propiedades ReleaseDate y precio con el atributo Tipo de
datos adecuado.
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[DataType(DataType.Currency)]
public decimal Price { get; set; }
El atributo DataType slo proporcionan consejos para el motor a fin de dar formato a
los datos (y los atributos de suministro como <a>
para URL y <a
href="mailto:EmailAddress.com"> por correo electrnico. Puede utilizar el atributo
RegularExpression para validar el formato de los datos. El atributo DataType se utiliza
para especificar el tipo de datos que es ms especfico que el tipo intrnseco base de
datos, que no atribuye validacin. En este caso, slo queremos hacer un seguimiento
de la fecha, no la fecha y la hora. La enumeracin DataType ofrece para muchos tipos
de datos, como fecha, hora, Fax, vigencia EmailAddress y ms. El atributo DataType
tambin puede activar la aplicacin para proporcionar automticamente las
caractersticas especficas del tipo, por ejemplo, a. mailto: enlace se pueden crear
para DataType.EmailAddress, y un selector de fecha se pueden proporcionar para
DataType.Date en los navegadores que soportan HTML5. El atributo DataType emite
datos HTML 5 (que se pronuncia data dash) atribuye que los navegadores HTML 5
puedan entender. Los atributos DataType no proporcionan ninguna validacin.
DataType.Date no especifica el formato de la fecha que se muestra. Por defecto,
el campo de datos se muestra de acuerdo con los formatos predeterminados basados
en CultureInfo del servidor.
El atributo formatSalida se utiliza para especificar explcitamente el formato de fecha:
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}",
ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; }
El ajuste ApplyFormatInEditMode especifica que el formato especificado tambin debe
aplicarse cuando el valor se muestra en un cuadro de texto para su edicin. (Es
posible que no desee que para algunos campos - por ejemplo, para los valores de la
moneda, es posible que no desee que el smbolo de la moneda en el cuadro de
texto para su edicin.). Puede puede utilizar el atributo formatSalida por s
mismo, pero es generalmente una buena idea utilizar el atributo DataType tambin. El
atributo DataType transmite la semntica de los datos en comparacin con el modo de

86

hacer en una pantalla, y proporciona los siguientes beneficios que no se consigue


con formatSalida:
El navegador puede habilitar las caractersticas de HTML5 (por ejemplo, para
mostrar un control de calendario, el smbolo de moneda de la configuracin
regional apropiada, enlaces de correo electrnico,etc.).
Por defecto, el navegador representar datos con el formato correcto basado
en la configuracin regional.
El atributo DataType puede permitir MVC para elegir la plantilla de
campo derecho
de representar
los
datos (la formatSalida si se
usa
solo utiliza la plantilla de cadena).
Si se utiliza el atributo DataType con un campo de fecha, se tiene que especificar el
atributo formatSalida tambin con el fin de asegurarse de que el campo se representa
correctamente en los navegadores Chrome.
El cdigo siguiente muestra los atributos que combinan en una sola lnea:

public class Movie


{
public int ID { get; set; }
[Required,StringLength(60, MinimumLength = 3)]
public string Title { get; set; }
[Display(Name = "Release Date"),DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Required]
public string Genre { get; set; }
[Range(1, 100),DataType(DataType.Currency)]
public decimal Price { get; set; }
[Required,StringLength(5)]
public string Rating { get; set; }
}

Examinar los mtodos Details y Delete


En esta parte del tutorial, examinar los mtodos Details generados automticamente y
Delete.
Abra el Movie Controller y examinar el mtodo de details.

87

public ActionResult Details(int? id)


{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}

El motor de andamios MVC que cre este mtodo de accin agrega un


comentario que muestra una peticin HTTP que invoca el mtodo. En este caso se
trata de una peticin GET con tres segmentos de URL, el controlador de Cine, el
mtodo de detalles y un valor de ID.
Code First hace que sea fcil de buscar datos utilizando el mtodo Find. Una
caracterstica importante de seguridad incorporada en el mtodo es que el
cdigo verifica que el mtodo Find ha encontrado una pelcula antes de que el cdigo
intentara hacer algo con ella. Por ejemplo, un hacker podra introducir errores en el
sitio cambiando
la URL creado
por los
enlaces
desde http: //localhost:xxxx/Movies/Details/1 a
algo
como http: //localhost:xxxx/Movies/Details/12345 (o
algn
otro
valor que
no
represente una
pelcula
real).
Si no
marc para
una
pelcula nulo, una
pelcula nula dara lugar a un error de base de datos.
Examinar los mtodos de eliminar y DeleteConfirmed.

// GET: /Movies/Delete/5

88

public ActionResult Delete(int? id)


{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
// POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Movie movie = db.Movies.Find(id);
db.Movies.Remove(movie);
db.SaveChanges();
return RedirectToAction("Index");
}

Tenga en cuenta que el mtodo HTTP GET, no se elimina la pelcula


especificado Eliminar,
devuelve una
vista
de
la pelcula donde
se
puede presentar (HttpPost) la eliminacin. Realizacin de una operacin de
eliminacin en respuesta a una peticin GET (o para el caso, la realizacin de una
operacin
de
edicin,
cree operacin, o
cualquier
otra operacin
que
cambie datos) abre un agujero de seguridad.
El mtodo HttpPost que borra los datos se denomina DeleteConfirmed para dar el
mtodo HTTP POST una firma o nombre nico. Las dos firmas de los mtodos se
muestran a continuacin:
// GET: /Movies/Delete/5
public ActionResult Delete(int? id)
//
// POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)

89

El Common Language Runtime (CLR) requiere mtodos sobrecargados para


tener una firma nica de parmetros (mismo nombre de mtodo, pero diferente lista
de parmetros). Sin embargo, aqu se necesitan dos mtodos Eliminar - uno para
GET y otro para la POST - que ambos tienen la misma firma parmetro.
(Ambos tienen que aceptar un solo entero como parmetro.)
Para solucionar esto, se puede hacer un par de cosas. Una es la de dar a
los mtodos diferentes nombres. Eso es lo que el mecanismo de Scaffolding hizo en el
ejemplo anterior. Sin embargo, esto presenta un pequeo problema: en ASP.NET los
segmentos de una URL a los mapean mtodos de accin por su nombre, y si cambia
el nombre de un mtodo, el enrutamiento normalmente no sera capaz de encontrar
ese mtodo. La solucin es lo que se ve en el ejemplo, que consiste en aadir el
atributo
ActionName ("Delete")
para el
mtodo DeleteConfirmed.
Esto
realiza efectivamente mapeo para el sistema de enrutamiento para que una URL que
incluya /Delete/ para una solicitud POST se encuentra el mtodo DeleteConfirmed.
Otra forma comn para evitar un problema con mtodos que tienen nombres y
firmas idnticas es cambiar artificialmente la firma del mtodo POST para incluir un
parmetro no utilizado. Por ejemplo, algunos desarrolladores agregar un tipo de
parametro FormCollection que se pasa al mtodo POST, y luego simplemente no
usan el parmetro:
public ActionResult Delete(FormCollection fcNotUsed, int id = 0)
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
db.Movies.Remove(movie);
db.SaveChanges();
return RedirectToAction("Index");
}

Resumen
Ahora tiene una aplicacin completa ASP.NET MVC que almacena los datos en
una base de datos local DB. Puede crear, leer, actualizar, eliminar y buscar pelculas.

90

91

Das könnte Ihnen auch gefallen