ASP.NET MVC (2011)

Preview:

DESCRIPTION

In this presentation a complete ASP.NET MVC introductory course is developed. Every key aspect of MVC is covered and some examples are developed.

Citation preview

ACTIVE SERVER PAGES .NET 4.0

MODELO-VISTA-CONTROLADORMVC 2 Y 3

RAZOR ENGINE

Nombre del Instructor

¿Qué es un patrón de arquitectura de software? Es una norma de diseño establecida

en el campo de la Ingeniería de Software.

Es un concepto que establece ciertos elementos importantes de una arquitectura de software No es la arquitectura en sí misma

Ejemplos: ETL (servicios de integración RDBMS) / DataWarehouse/ Modelo Entidad-Relación, etc.

¿Qué es el patrón de arquitectura MVC? MODELO-VISTA-CONTROLADOR Es un patrón de arquitectura de

software. VISTA: representación visual de la

información del modelo. MODELO: representa uno o más objetos

con un estado determinado. CONTROLADOR: es lo que puede

alterar el estado del modelo.

MVC – Perspectiva 1

Browser

1. Petición

HTTP

CCONTROLADOR

2. Parámetros de ejecución

M MODELO

3. Colección datos

resultado

V

VISTA

3.

Cole

cció

n

dato

s re

sult

ad

o4.C

on

tenid

o

de in

terfa

z usu

ario

5. Contenido HTTP

CLIENTE SERVIDORLos componentes M, V y C están del lado servidor.

MODELO

2. Parámetros de ejecución

M MODELO

3. Colección datos

resultado

Los objeto de modelo•Implementan la lógica del dominio de la aplicación.•Suelen leer y persistir estados en una RDBMS.•En sistemas grandes pueden tener una capa de acceso a datos (DAL) separada.

VISTA

V

VISTA

3.

Cole

cció

n

dato

s re

sult

ad

o4.C

on

tenid

o

de in

terfa

z usu

ario

“Arma” la interfaz de usuario.• Los datos que muestra son estados del objeto que están gestionando•Utiliza controles comunes de la GUI en cuestión (cajas de texto, dropdownlists, checkboxes)

VISTA

V

VISTA

3.

Cole

cció

n

dato

s re

sult

ad

o4.C

on

tenid

o

de in

terfa

z usu

ario

La GUI se construye con elementos propios de la tecnología que se utilice Cliente liviano (por lo general, HTML o

formularios XML) Cliente pesado (dependerá de la

plataforma, etc.)HTML/XMLWinForms .NETFormularios JavaVisual FoxProVisual BasicDelphiPowerBuilder

CONTROLADOR1.

Petición HTTP

CCONTROLADOR

2. Parámetros de ejecución

3. Colección datos

resultado5. Contenido

HTTP

Es el componente que •Maneja la interacción con el usuario y en función de eso..•..envía mensajes al modelo para modificar su estado (es decir, cambia el valor de sus miembros, etc.)•Selecciona en último término el tipo de vista que exhibirá al cliente en la GUI.

Acople fuerte Dos clases están fuertemente acopladas

cuando Una clase dependiente A tiene un fuerte

“conocimiento”, o hace un uso intensivo, de las definiciones existentes en otra clase B

A implementa un puntero directo a una clase concreta que aporta el conocimiento necesario

La dependencia sobre B no se puede cambiar sin reprogramar la clase A

AB

Inicio()Saldo()Nuevo()Fin()

Acople débil Dos clases están débilmente acopladas

cuando Una clase dependiente A no tiene conocimiento (o

bien hace poco uso) de las definici0nes existentes en otra clase B

A implementa un puntero sólo a una interfaz, la cual puede estar implementada por varias clases concretas que aportan el conocimiento necesario

La dependencia de A se limita sólo al “contrato” de la interfaz que expone B.

AinterfazB

Inicio()Saldo()Nuevo()Fin()

Empleado

Inicio()Saldo()Nuevo()Fin()

Director

Inicio()Saldo()Nuevo()Fin()

MVC es acople débil

Existe acople débil entre los tres componentes MVC

Permite el enfoque profundo en cada uno de estos elementos, de a uno por vez

Facilita el testing automático En ASP.NET WebForms existe una sola clase

para mostrar salida y manejar la entrada de usuario.

Hay que instanciar toda la cadena de objetos para probarla.

Con MVC las pruebas se remiten a un solo componente aislado de la presentación

Motor de vista “Razor”

Todo ASP.NET MVC tiene incorporado el concepto de “motor de vista” Genera las vistas de acuerdo al tipo de

cliente final (smart client, thin client, etc.)

Si son páginas HTML finales, el motor por defecto es ASP.NET con master pages

Con MVC 3 se agrega un nuevo motor de representación (rendering) de páginas: RAZOR

Proyecto ASP.NET MVC 3

Usar marcación de HTML5A través de Modernizr 1.7

¿Y qué es Modernizr?

Es una librería para detectar el uso de HTML5 + CSS3 y su correspondiente soporte (o no) en el browser.

Si el browser es compatible, se habilitan los nuevos estilos y marcaciones

Objetivos de Razor Engine Compacto: minimiza la cantidad de tipeo en un

archivo Fácil: es sencillo de aprender y permite ser

productivo con un mínimo de conceptos No es un nuevo lenguaje: se utilizar VB/CS

dentro del HTML conocido, para producir un nuevo tipo de construcción HTML

Cualquier editor de texto (incluso notepad.exe)

Soporte completo de Intellisense en VS 2010 Verificable por unidades: no se exige el uso

de un controlador ni de un servidor web, soporta vistas de prueba unitarias.

EJERCICIO

1. Crear la aplicación en VS2010 Hacer clic en New/ Project Seleccionar el tipo de proyecto

.NET 4.0 Framework Tipo ASP.NET MVC 3 Web Application Nombre: “MVC3RunWebCamp” Localización: “C:\ MVC3RunWebCamp” ACEPTAR

1.1 Proyecto de test

VS2010 crea dos proyectos en MVC 1. El proyecto MVC3RunWebCamp en sí mismo 2. Un proyecto para probar la aplicación,

denominado XXX.test, donde XXX es el nombre que dimos a nuestro proyecto original

2. Configurar el puerto TCP de escucha en 50000 Hacer clic con botón derecho sobre la raíz del proyecto

en el explorador de soluciones. Seleccionar la ficha Web. Seleccionar Puerto específico, escribir 50000 y guardar

todo.

3. Estructura de carpetas

A continuación comentaremos algo acerca de las carpetas creadas en estos proyectos

Proyecto MVC3.. de ASP.NET 4.0

Proyecto de testing (VS2010 Ultimate o Test)

3.1 App_Data

Es la carpeta de almacenamiento físico de datos.

Su papel es similar al de la misma carpeta en una aplicación ASP.NET regular

3.2 Content

Esta carpeta se recomienda para contenido estático Hojas de estilo en

cascada Imágenes Temas Archivos de medios,

etc.

3.3 Controllers Contiene la definición de

clases de los controladores Manejo de interacción con

el usuario Manipulación del modelo Elección última de la

interfaz de usuario Por convención del

framework, su nombre debe terminar con la palabra Controller

3.4 Models

Contiene clases que representan el modelo de aplicación

Código define los objetos define la interacción con

el almacén de datos Por defecto, el bibliotecas

de clase separadas (se pueden mover a otra carpeta luego)

3.5 Scripts

De existir, aquí se colocan los programas JavaScript Algunos módulos son de

uso propio de Intellisense (ver donde dice “vsdoc”)

Otros son para dar soporte a AJAX

Otros son para validación de datos, funciones que se insertan en las vistas ASPX

3.6 Views Contiene los componentes que

muestran la interfaz de usuario según engine: .ascx, .aspx, .master para

ASP.NET convencional Vbhtml / Cshtml para RAZOR archivos relacionados con la

producción de HTML final

Contiene una vista por cada controlador. Para un controlador ClienteController existirá una vista Cliente.Cuando ASP.NET MVC busca una vista, ubica un archivo .aspx con el nombre especificado en \Views\nombre_controlador\nombre_acción.aspx

3.6 Views Por defecto, ASP.NET MVC

crea tres carpetas con vistas: Account: vista de la cuenta,

gestionada por AccountController

Home: vista de página principal, gestionada por HomeController

Shared: es la única carpeta que puede estar asociada a varios controladores al mismo tiempo

4. Enrutamiento MVC MVC “mapea” URLs a las clases que

son los controladores Las URLs entrantes no se refieren a

recursos físicos en el servidor ASP.NET 4.0 tiene esta nueva

característica denominada “enrutamiento”

Se crea un conjunto de reglas de enrutamiento en el archivo Global.asax

El enrutamiento también está disponible para WebForms 4.0 regulares de ASP.NET

WEB FORMS 4 - Enrutamiento Las URL como ésta no son amigables para

los motores de búsqueda:http://www.mysite.com/products.aspx?category=software

En cambio, éstas si lo son:http://www.mysite.com/products/software

El enrutamiento en ASP.NET 4.0 permite que la aplicación acepte requerimientos que no se mapean a archivos físicos

Se usa una URL “semántica” que tiene sentido para el usuario y es amigable para los optimizadores de motores de búsqueda.

WEB FORMS 4 - Enrutamiento

HTTP REQUESTProducts/Bikes

Enrutamiento ASP.NET

Ruta:Product/{name} -> Product.aspx

Página WebForm

Nombre de archivoProduct.aspx

Valores de la ruta:Name = “Bikes”

RESPUESTA

Shared Sub RegisterRoutes(ByVal routes As RouteCollection)

routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

' MapRoute toma los siguientes parámetros, en orden:

' (1) nombre de la ruta

' (2) URL con parámetros

' (3) Parámetros por defecto

routes.MapRoute( _

"Default", _

"{controller}/{action}/{id}", _

New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional} _

)

End Sub

4. Enrutamiento en Global.asax

4. Enrutamiento MapPageRoute con ASP.NET WebForms 4.0

5. HomeController

http://localhost/index llamará a la funcion Index() del tipo ActionResult

http://localhost/about llamará a la función About() del tipo ActionResult

<HandleError()> _Public Class HomeController Inherits System.Web.Mvc.Controller

Function Index() As ActionResult ViewData("Message") = "Welcome to ASP.NET MVC!"

Return View() End Function

Function About() As ActionResult Return View() End FunctionEnd Class

5. HomeController

Los métodos mapeados deben Ser públicos No deben tener NonActionAtribute Siempre devolver un objeto del tipo ActionResult

<HandleError()> _Public Class HomeController Inherits System.Web.Mvc.Controller

Function Index() As ActionResult ViewData("Message") = "Welcome to ASP.NET MVC!"

Return View() End Function

Function About() As ActionResult Return View() End FunctionEnd Class

5.1 Distintos tipos de ActionResult

Clase Descripción

ViewResult Salida HTML

EmptyResult Salida vacía, sin salida

RedirectResult Redirección a otra URL

JSONResult Resultado del tipo JavaScript Object Notation

JavaScriptResult

Un script de JavaScript

ContentResult Un resultado que contiene texto

FileContentResult

Un archivo descargable con contenido binario

FilePathResult Un archivo descargable con un camino (path)

FileStreamResult

Un archivo descargable con un stream de datos

ActionResult Lo que retorna el controlador luego de su ejecución•Armado de una vista•Redirección a otra acción•Redirección a otra página

5.2 VIEW() Normalmente, no se devuelve directamente

ViewResult(), sino el método View() de la clase de base del Controlador

Es decir, no retornamos un objeto ActionResult directamente Más bien llamamos a los métodos de la clase de

base del controlador Para pasar datos a la vista se utiliza la

propiedad ViewData de la clase ControllerBase

5.2 VIEW()

Viewdata diccionario ViewDataDictionary con objetos

En HomeController Los métodos ajustan los valores en el diccionario ViewData Y devuelven la vista asociada a la acción llamando a View()

<HandleError()> _Public Class HomeController Inherits System.Web.Mvc.Controller

Function Index() As ActionResult ViewData("Message") = "Welcome to ASP.NET MVC!"

Return View() End Function

Function About() As ActionResult Return View() End FunctionEnd Class

5.3 Métodos de clase de base del controlador

Métodos Retorna una instancia de:

View ViewResult

Redirect RedirectResult

RedirectToAction

RedirectToRouteResult, es decir, redirecciona a la acción especificada

RedirectToRoute RedirectToRouteResult, es decir, redirecciona a la ruta especificada.

JSON JsonResult

JavaScriptResult

JavaScriptResult

Content ContentResult

File Dependiendo de los parámetros pasados al método retorna:•FileContentResult•FilePathResult•FileStreamResult

6. ViewData Es la propiedad de vista específica

de MVC Para producir una salida visible:

1. Se debe interactuar con el diccionario existente en ViewData

ViewData(“Message”)=“Bienvenidos..”

2. Se debe devolver el resultado de View()

Function Index() As ActionResult ViewData("Message") = “Bienvenidos al MUG" Return View()End Function

7. Examinando las vistas Una carpeta por

controlador Account Home

Dentro de cada carpeta Archivos aspx,

ascx O bien vbHtml, etc.

En Shared Vistas en uso por

más de un controlador

7.1 Vistas ASPX

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %><asp:Content ID="aboutTitle" ContentPlaceHolderID="TitleContent" runat="server"> About Us</asp:Content><asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server"> <h2>About</h2> <p> Put content here. </p></asp:Content>

Son archivos regulares de ASP.NETPor ejemplo, About.aspxAquí, es una vista que todavía no tiene contenido dinámico definido.

7.1 Vistas RAZOR

@Code ViewData("Title") = "About Us"End Code

<h2>About</h2><p> Put content here.</p>

Tienen la extensión VBHTML ó CSHTML

7.2 Vistas

Las vistas, por defecto, no contienen código ejecutable

El controlador pasa la información a ser exhibida a través del diccionario ViewData.

7.3 Vistas ASPX

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server"> Home Page</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server"> <h2><%: ViewData("Message") %></h2> <p>To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.</p></asp:Content>

Index.aspx si tiene contenido dinámicoNótese como ViewData(“Message”) realiza la exhibición de datos

7.3 Vistas Razor

@Code ViewData("Title") = "Home Page"End Code

<h2>@ViewData("Message")</h2><p> To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.</p>

Index.aspx si tiene contenido dinámicoNótese como ViewData(“Message”) realiza la exhibición de datos

???

7.3.1 ASPX vs. RAZOR<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server"> Home Page</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server"> <h2><%: ViewData("Message") %></h2> <p>To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.</p></asp:Content>

@Code ViewData("Title") = "Home Page"End Code

<h2>@ViewData("Message")</h2><p> To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.</p>

RAZOR VBHTML

ASP.NET ASPX

8. Ruta por defecto http://localhost:50000 se intercepta

por el mecanismo de intercepción y enrutamiento de ASP.NET 4.0 La URL no especifica ningún controlador,

luego ASP.NET MVC: instancia por defecto HomeController Invoca a una acción por defecto Index Todo esto definido en Global.asax

routes.MapRoute( _ "Default", _ "{controller}/{action}/{id}", _ New With {.controller = "Home", _ .action = "Index", _ .id = UrlParameter.Optional} )

9. Agregar un Entity Data Model Para manejar los datos de la base de

datos, creamos un Entity Data Model de ADO.NET Entity Framework 4.0 Utilizaremos la base de datos

AdventureWorksLT Hacer clic con botón derecho sobre

la carpeta Models. Luego Agregar (add), nuevo ítem.

Seleccionar ADO.NET Entity Data Model.

Dar nombre al modelo: AW1.edmx Se abre un asistente.

9.1 Elegir contenido del modelo Seleccionar “Generar desde base de

datos” y hacer clic en Siguiente Creamos la conexión a

AdventureWorksLT, una instancia simplificada de la base de datos Provea el nombre del servidor SQL (localhost) Indique nombre de usuario y contraseña para

SQL Server, tipo de autenticación por SQL Server

Nombre de la base de datos AdventureWorksLT

Clic en Aceptar para crear la conexión

9.1.1 Se puede crear una conexión a un MDF El archivo MDF (master data file) es el

principal de SQL Server, donde aloja los espacios de tabla, catálogo y objetos grandes.

Este asistente permite también crear un nuevo string de conexión y especificar la locación de este archivo MDF

En este ejercicio utilizaremos AdventureWorksLT (simplificada) Recuerde de crear una conexión a dicha

bases de datos primero

9.2 Seleccionar tablas Seleccione las

siguientes tablas Address Customer CustomerAddress

Con ellas formaremos la entidad “Domicilio” del cliente.

Clic en Finalizar

9.3 Verificar AW1.edmx VS2010 crea el modelo AW1.edmx

en la carpeta Models. Verificar que contenga los vínculos,

que éstos sean correctos, etc.

9.4 Implementar el repositorio Haga clic con botón derecho sobre el

proyecto MVC3RunWebCamp Cree un nuevo ítem de código Denomínelo AdventureWorksRepository.vb

El repositorio proporciona métodos para acceder a los datos subyacentes, a través de ADO.NET Entity Framework

Damos el código necesario paso a paso

Public Class AdventureWorksRepository

Private context As New AdventureWorksLTEntities()

‘colocar el codigo aquí

End Class

9.4.1 Codificar la clase de repositorio

El primer miembro a definir será el contexto AdventureWorksLTEntities quedó definido

al crear el modelo AW1, en su archivo .designer.vb

Public Function GetCustomers(ByVal page As Integer, ByVal size As Integer) As IEnumerable(Of Customer)

Return context.Customer.OrderBy(Function(c) _

c.CustomerID).Skip(page * size).Take(size)

End Function

Public Function GetCustomerById(ByVal customerId As Integer) As Customer

Return context.Customer.Include( _

"CustomerAddress.Address").Where(Function(c) _

c.CustomerID = customerId).First()

End Function

9.4.2 Recuperación de entidad Customer

Public Sub AddAddress(ByVal address As Address, ByVal customerId As Integer)

address.rowguid = Guid.NewGuid()

address.ModifiedDate = DateTime.Now

context.AddObject("Address", address)

Dim customerAddress As New CustomerAddress()

customerAddress.Address = address

customerAddress.Customer = GetCustomerById(customerId)

customerAddress.rowguid = Guid.NewGuid()

customerAddress.ModifiedDate = DateTime.Today

context.AddObject("CustomerAddress", customerAddress)

context.SaveChanges()

End Sub

9.4.3 Adición de domicilio a un cliente existente

Public Sub AddAddress(ByVal address As Address, ByVal customerId As Integer)

address.rowguid = Guid.NewGuid()

address.ModifiedDate = DateTime.Now

context.AddObject("Address", address)

Dim customerAddress As New CustomerAddress()

customerAddress.Address = address

customerAddress.Customer = GetCustomerById(customerId)

customerAddress.rowguid = Guid.NewGuid()

customerAddress.ModifiedDate = DateTime.Today

context.AddObject("CustomerAddress", customerAddress)

context.SaveChanges()

End Sub

9.4.3 Adición de domicilio a un cliente existente

Public Sub UpdateAddress()

context.SaveChanges()

End Sub

9.4.4 Grabar la dirección

SaveChanges quedó también definido en el modelo de entidad AW1.edmx

Public Sub DeleteAddress(ByVal address As Address, _

ByVal customerId As Integer)

Dim customerAddress As CustomerAddress = _

GetCustomerAddressById(address.AddressID, _

customerId)

context.DeleteObject(address)

context.DeleteObject(customerAddress)

context.SaveChanges()

End Sub

9.4.5 Eliminar la dirección

Public Function GetAddressById(ByVal addressId As Integer) As Address

Return context.Address.Where(Function(a) _

a.AddressID = addressId).First()

End Function

9.4.6 Recuperar la dirección

Public Function GetCustomerAddressById( _ ByVal addressId As Integer, _ ByVal customerId As Integer) As CustomerAddress

Return context.CustomerAddress.Where(Function(a) _ a.AddressID = addressId _ AndAlso a.CustomerID = customerId).First()

End Function

10. Implementar CustomerViewData (MVC view) Una vez creada la entidad y su

repositorio, se deben crear las vistas (views) de MVC Cree una carpeta ViewData debajo del

nodo principal del proyecto MVC3RunWebCamp.

Dentro de ViewData, cree una nueva clase llamada CustomerViewData

Codifíquela así:Public Class CustomerViewData Public Property Customers As IEnumerable(Of Customer) Public Property PreviousPage As Integer Public Property NextPage As Integer End Class

11. Implementar AddressViewData (MVC view) Dentro de la carpeta ViewData, cree otra

nueva clase llamada AddressViewData Codifíquela así:

Public Class AddressViewData Public Property Address As AddressPublic Property CustomerId As Integer

End Class

12. Implementar CustomerController

Tendrá dos métodos de acción: Index view: vista en forma de lista de

los clientes Info view: vista individual de la

información de un cliente Clic derecho sobre la carpeta Controllers Add Seleccionar el tipo de ítem Controller Dar nombre CustomerController Aceptar

12.1 CustomerController

El código por defecto que genera VS2010 es el siguiente:

Namespace MVCApp1 Public Class CustomerController Inherits System.Web.Mvc.Controller

' ' GET: /Customer

Function Index() As ActionResult Return View() End Function

End ClassEnd Namespace

12.2 CustomerController

Instanciar un repositorio

Namespace MVCApp1 Public Class CustomerController Inherits System.Web.Mvc.Controller

Private repository As New AdventureWorksRepository()

' ' GET: /Customer

Function Index() As ActionResult Return View() End Function

End ClassEnd Namespace

12.3 CustomerController – Index()

Crear el método de acción para manejar la vista CustomerControllerIndex.

Sobreescribir el método Index por defecto, con el siguiente código

Public Function Index(ByVal page As Nullable(Of Integer)) _

As ActionResult Dim viewData = New CustomerViewData() Dim currentPage As Integer = If(page, 0) viewData.Customers = _ Me.repository.GetCustomers(currentPage, 10) viewData.NextPage = currentPage + 1 viewData.PreviousPage = _

If((currentPage <= 0), 0, currentPage - 1) Return View(viewData) End Function

12.4 CustomerController – Info()

Crear el método de acción para manejar la vista CustomerControllerInfo.

Agregar el siguiente método:

Public Function Info(ByVal id As Integer) As ActionResult Dim customer = Me.repository.GetCustomerById(id) Return View(customer)End Function

12.5 AddressController Gestiona dos vistas

Vista Edit: modificar el domicilio de un cliente

Vista New: agregar un nuevo domicilio a un cliente

Agregar un controlador a Controllers Denominado AddressController Marcar “agregar métodos de acción para

los escenarios crear, actualizar, eliminar y detalles”

12.6 AddressController Instanciar un repositorio para

servicio de acceso a datos.

Public Class AddressController Inherits System.Web.Mvc.Controller Private repository As AdventureWorksRepository = _ New AdventureWorksRepository() ... End Class

12.7 AddressController- Eliminar Index() y Details() por defecto Eliminar las siguientes líneas de los métodos por defecto:

' GET: /Address Function Index() As ActionResult Return View() End Function‘' GET: /Address/Details/5 Function Details(ByVal id As Integer) As _ ActionResult Return View() End Function

12.8 AddressController - Crear el manejador de la vista Create. Reemplace el código de Create() de la

operación GET: Address/Create actual por el siguiente:

Function Create(ByVal customerId As Integer) As _ ActionResult Dim addressViewData = New AddressViewData With {

.CustomerId = customerId } Return View(addressViewData)End Function

12.9 AddressController - Crear el manejador de envío de formularios Reemplace el código de Create() de la

operación POST: Address/Create actual por el siguiente:

<AcceptVerbs(HttpVerbs.Post)> _ Function Create(ByVal customerId As Integer, _ ByVal collection As FormCollection) As ActionResult Try Dim addressViewData = New AddressViewData() UpdateModel(addressViewData) Me.repository.AddAddress(addressViewData.Address, _ customerId) Return RedirectToAction("Info", "Customer", _ New With {.id = customerId}) Catch Return View() End TryEnd Function

12.10 Crear el manejador de presentación de vista Edit Reemplace el código de Edit de la operación POST actual por el siguiente:

<AcceptVerbs(HttpVerbs.Post)> _Public Function Edit(ByVal addressId As Integer, _ ByVal customerId As Integer, _ ByVal collection As FormCollection) As _ ActionResult Try Dim addressViewData As New AddressViewData() addressViewData.Address = _ Me.repository.GetAddressById(addressId) UpdateModel(addressViewData) Me.repository.UpdateAddress() Return RedirectToAction("Info", "Customer", _ New With {.id = customerId}) Catch Return View() End TryEnd Function

12.10.1 AddressControllerQué hace la vista Edit

Recupera (a través del repositorio) la entidad Address que corresponde al parámetro AddressID recibido

Actualiza la entidad Address usando el formulario enviado por el browser a través del método UpdateModel

Actualiza la base de datos utilizando el repositorio Regresa a la vista de información de cliente (vista Info)

a través del método RedirectToAction

addressViewData.Address = _ Me.repository.GetAddressById(addressId) UpdateModel(addressViewData) Me.repository.UpdateAddress() Return RedirectToAction("Info", "Customer", _ New With {.id = customerId})

12.11 Implementar la eliminación de un domicilio Agregar el siguiente método Delete

a la clase AddressController:

Public Function Delete(ByVal addressId As Integer, _ByVal customerId As Integer) As ActionResult

Dim address = Me.repository.GetAddressById(addressId) Me.repository.DeleteAddress(address, customerId) Return RedirectToAction("Info", _ "Customer", _ New With {.id = customerId}) End Function

12.12 Crear la vista Index de CustomerController1. Abrir el código del método Index

en CustomerController2. Clic con botón derecho3. Seleccionar “Add View”

12.12.1 Cuadro de diálogo de crear vista Index.aspx

Configurar como se muestra en el cuadro de diálogo

Pulsar Add SE CREA

INDEX.vbhtml

12.13 Con ASPX, la página Index.aspx recién creada sería

Código fuente

Vista diseño

12.13.1 Con RAZOR la página recién creada es:

Código fuente

Vista diseño = ?

12.14 Codificar Lista de cliente en la vista index.aspx<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2> customers</h2> <ul> <% For Each customer In ViewData.Model.Customers %> <li> <%= Html.ActionLink(customer.CompanyName + " - " + _ customer.FirstName + " " + _ customer.LastName, "Info", _ New With {.id = customer.CustomerID}) %> </li> <% Next %> </ul></asp:Content> For-Each recorre la colección Customers existente en el modelo de datos

12.14.1 Codificar Lista de cliente en la vista index.vbhtml@Code ViewData("Title") = "Index"End Code<h2>customers</h2><ul>@For Each customer In ViewData.Model.Customers@<li> @Html.ActionLink(customer.CompanyName + "-" + _ customer.FirstName + " " + _ customer.LastName, "Info", _ New With {.id = customer.customerID})</li>Next</ul>

For-Each recorre la colección Customers existente en el modelo de datos

12.15 Crear la vista Info de CustomerController

1. Abrir el código del método Info en CustomerController

2. Clic con botón derecho3. Seleccionar “Add View”

12.15.1 Cuadro de diálogo de crear vista Info.aspx

Configurar cómo se muestra en el cuadro de diálogo

Pulsar Add SE CREA

INFO.vbHtml

12.16 Colocar HTML en info.aspx de customer<h2>

Customer Information</h2> <fieldset> <p> CompanyName: <%= Html.Encode(Model.CompanyName) %> </p> <p> EmailAddress: <%= Html.Encode(Model.EmailAddress) %> </p> <p> Name: <%= Html.Encode(Model.Title + " " + Model.FirstName + " " + Model.MiddleName + Model.LastName) %> </p> <p> Phone: <%= Html.Encode(Model.Phone) %> </p> </fieldset>

12.16.1 O editar Info.vbhtml<h2> Customer Information</h2> <fieldset> <p> CompanyName: @Html.Encode(Model.CompanyName) </p> <p> EmailAddress: @Html.Encode(Model.EmailAddress) </p> <p> Name: @Html.Encode(Model.Title + " " + Model.FirstName + " " + Model.MiddleName + Model.LastName) </p> <p> Phone: @Html.Encode(Model.Phone) </p> </fieldset>

12.17 Agregue el detalle de las direcciones del cliente (ASPX) El siguiente código va debajo <fieldset> pero dentro

de </asp:Content> en la vista info.aspx de customer

<ul><% For Each address In Model.CustomerAddress%> <li> <%= address.Address.AddressLine1 + " " + _ address.Address.AddressLine2 + " - " + _ address.Address.City %> <%= Html.ActionLink("(Edit)", "Edit", "Address", _ New With {address.AddressID, Model.CustomerID}, _ Nothing) %> <%= Html.ActionLink("(Delete)", "Delete", "Address", _ New With {address.AddressID, Model.CustomerID}, _ Nothing) %> </li> <% Next %></ul><%= Html.ActionLink("Add New Address", "Create", "Address", _ New With {Model.CustomerID}, Nothing) %>

12.17.1 Agregue el detalle de las direcciones del cliente (vbHTML)

El siguiente código va debajo <fieldset> pero dentro de </asp:Content> en la vista info.vbhtml de customer

<ul>@For Each address In Model.CustomerAddress @<li> @address.Address.AddressLine1 + " " + _ address.Address.AddressLine2 + " - " + _ address.Address.City %> @Html.ActionLink("(Edit)", "Edit", "Address", _ New With {address.AddressID, Model.CustomerID}, _ Nothing) @Html.ActionLink("(Delete)", "Delete", "Address", _ New With {address.AddressID, Model.CustomerID}, _ Nothing) </li> Next</ul>@Html.ActionLink("Add New Address", "Create", "Address", _ New With {Model.CustomerID}, Nothing)

12.18 Verificar lista de cliente en la vista index.aspx<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2> customers</h2> <ul> <% For Each customer In ViewData.Model.Customers %> <li> <%= Html.ActionLink(customer.CompanyName + " - " + _ customer.FirstName + " " + _ customer.LastName, "Info", _ New With {.id = customer.CustomerID}) %> </li> <% Next %> </ul></asp:Content> For-Each recorre la colección Customers existente en el modelo de datos

12.18.1 Verificar lista de cliente en la vista index.vbhtml@Code ViewData("Title") = "Index"End Code<h2>customers</h2><ul>@For Each customer In ViewData.Model.Customers@<li> @Html.ActionLink(customer.CompanyName + "-" + _ customer.FirstName + " " + _ customer.LastName, "Info", _ New With {.id = customer.customerID})</li>Next</ul>

For-Each recorre la colección Customers existente en el modelo de datos

12.19 Crear la vista Edit de AddressController

1. Abrir el código del método Edit en AddressController

2. Clic con botón derecho3. Seleccionar “Add View”

12.19.1 Cuadro de diálogo de crear vista Edit.aspx

Configurar como se muestra en el cuadro de diálogo

Clic en Add SE CREA

EDIT.vbhtml

12.20 Verificar Edit.aspx recién creado

Código fuente

12.21 HTML campos de domicilio /1@Code

ViewData("Title") = "Edit"End Code

<h2>Editing: @Model.Address.AddressLine1 %></h2>@Html.ValidationSummary("Edit was unsuccessful. " + _ "Please correct the errors and try again.")@Using (Html.BeginForm())@<fieldset><legend>Fields</legend><p><label for="AddressLine1">Address Line 1:</label>@Html.TextBox("Address.AddressLine1")</p><p><label for="AddressLine2">Address Line 2:</label>@Html.TextBox("Address.AddressLine2")</p>

Sigue en la próxima diapositiva

12.21 HTML campos de domicilio /2…viene de la diapositiva anterior<p><label for="City">City:</label>@Html.TextBox("Address.City")</p><p><label for="StateProvince">State/Province:</label>@Html.TextBox("Address.StateProvince")</p><p><label for="PostalCode">Postal Code:</label>@Html.TextBox("Address.PostalCode")</p><p><label for="CountryRegion">Country/Region:</label>@Html.TextBox("Address.CountryRegion")</p><p><input type="submit" value="Save" /></p></fieldset>End Using

12.22 Crear vista Nuevo Domicilio en AddressController

1. Abrir el código del método Create (GET) en AddressController

2. Clic con botón derecho3. Seleccionar “Add View”

12.22.1 Cuadro de diálogo de crear vista Edit.aspx

Configurar como se muestra en el cuadro de diálogo

Clic en Add SE CREA

Create.vbhtml

12.22.2 Verificar Create.vbhtml recién creada

Código HTML

12.23 Agregue HTML de los campos del nuevo domicilio (Create.aspx) <h2> Create Address </h2> @Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") @Using (Html.BeginForm()) @<fieldset> <legend>Fields</legend> <p> <label for="AddressLine1"> Address Line 1:</label> @Html.TextBox("Address.AddressLine1") </p> <p> <label for="AddressLine2"> Address Line 2:</label> @Html.TextBox("Address.AddressLine2") </p> <p> <label for="City"> City:</label> @Html.TextBox("Address.City") </p>

<p> <label for="StateProvince"> State/Province:</label> @Html.TextBox("Address.StateProvince")</p><p> <label for="PostalCode"> Postal Code:</label> @Html.TextBox("Address.PostalCode")</p><p> <label for="CountryRegion"> Country/Region:</label> @Html.TextBox("Address.CountryRegion")</p><p> <input type="submit" value="Create" /></p></fieldset>End Using

DEPURACION DE LA APLICACION

Correr la aplicación

Ir al árbol de objetos en Solution Explorer

Ubicar el proyecto MVCRunWebCamp.

Botón derecho -> Debug -> Start New Instance

Aplicación corriendo

Probar la lista de Customers Colocar en la URL:

Se debe exhibir la siguiente página:

http://localhost:50000/customer

Tabla de clientes

Pase de ID de cliente

El hipervinculo Metropolitan Sports Supply apunta a la siguiente URLhttp://localhost:50000/customer/Info/5

Donde se enruta según estos parámetros:

Info es la vista (info.aspx de customer) 5 es el ID de cliente a mostrar

http://localhost:50000/customer/info/5

Hacer clic en la opción de “Agregar una nueva dirección”, para dar de alta una nueva entrada en la colección de direcciones del cliente

http://localhost:50000/Address/Create?CustomerID=5

Rellenar los campos y hacer clic en Create

¿PREGUNTAS?

¡MUCHAS GRACIAS!

CARLOS PEREZ logica10@gmail.com Logica10mobile.blogspot.com