Vous êtes sur la page 1sur 18

Servicio de Informtica ASP.

NET MVC 3 Framework


Helpers bsico
HtmlHelpers Personalizados Personalizados con HTMLHelper Ejemplo prctico: Incluir buscador en nuestra aplicacin Vistas por defecto Listados. WebGrid

HTMLHelpers
Ayer vimos las funciones relacionadas con las direcciones. Hoy nos centramos en las que realmente nos van a ayudar en el trabajo diario, las que nos generan cdigo HTML. Aunque el listado es mucho ms amplio que el de URLHelpers, lo cierto es que todos son muy parecidos. Vamos a comenzar con el elemento bsico que es el formulario que recoge todos los campos con los que trabajamos. Nos creamos una mtodo / accin en nuestro controlador para ir jugando. Le podemos llamar helpers. No le vamos a pasar ningn modelo por el momento. Editamos su vista y lo bsico para un formulario en HTML es <form ...></form>. La idea es que no lo escribamos directamente sino que usemos los helpers.

BeginForm(s:action, s:controller, o:values)


Si escribimos

@using (Html.BeginForm()) { }

Nos generara el siguiente cdigo

<form action="/Home/helpers" method="post"></form>

Por defecto nos genera una accin a nosotros mismos y hace la llamada con mtodo post Con los parmetros podemos indicar que controlador / accin del action y el mtodo

Html.BeginForm("Create", "Libro", FormMethod.Get)

Y generara

<form action="/Libro/Create" method="get"></form>

Todos los HTMLHelpers incluyen un ltimo parmetro abierto a aadir cualquier atributo HTML, por ejemplo id, class, etc. En el caso de que queramos indicar el id

Html.BeginForm("Create", "Libro", FormMethod.Get, new {id="fTest"}))

Si adems quisiramos aadir el estilo con class al ser una palabra reservadas del sistema debemos escribir la propiedad con @class.

Html.BeginForm("Create", "Libro", FormMethod.Get, new {id="fTest", @class="formulario

El resultado final sera

<form action="/Libro/Create" class="formulario-ua" id="fTest" method="get"></form>

En caso de que no usemos using en la declaracin de beginform deberemos usar endform para indicar donde acaba.

@{ Html.BeginForm("Create", "Libro", FormMethod.Get, new {id = "fTest", @class = "formula ... @{ Html.EndForm();}

Yo usar en todos los ejemplos using porque queda el cdigo ms agrupado. Ahora es el momento de incluir elementos en el formulario

Label(s:name, o:text)
Un etiqueta con texto que hace referencia a un campo (name). En caso de que no se indique el texto pondr por defecto el nombre del campo que hayamos indicado en el primer parmetro.

@using(Html.BeginForm("Create", "Libro", FormMethod.Get, new {id = "fTest", @class = "for { @Html.Label("Nombre", "Nombre:") ... }

En este ejemplo mostrar una etiqueta "Nombre:" que hace referencia a un campo "Nombre".

<label for="Nombre">Nombre:</label>

TextBox(s:name, o:value)
Crea una caja de texto con el nombre que le indiquemos y con un valor por defecto en el segundo parmetro.

@Html.TextBox("Nombre", "Alberto")

genera

<input id="Nombre" name="Nombre" type="text" value="Alberto" />

Todo el contenido que se asigne en el valor por defecto (en cualquier HTMLHelper) se codifica automticamente para evitar que se produzcan ataques XSS injection.

CheckBox(s:name, b:checked)
Genera una elemento checkbox.

DropDownList(s:name, list:selectlistitems)
Genera una lista desplegable en la que podemos seleccionar un nico elemento.

@Html.Label("Sexo") @Html.DropDownList("Sexo", new MultiSelectList(new[] {"Hombre", "Mujer"}))

Genera

Hidden(s:name, o:value)
Genera un campo oculto.

ListBox(s:name, list:selectlistitems)
Genera una lista de valores en la que podemos seleccionar ms de un elemento.

@using(Html.BeginForm("Create", "Libro", FormMethod.Get, new {id = "fTest", @class = "for { @Html.Label("Unidad") @Html.ListBox("Unidad", new MultiSelectList(new[] {"Servicio de Informtica", "Selecc }

Genera

RadioButton(s:name, o:value, b:checked)


Genera una elemento radiobutton

TextArea(s:name, s:value)
Crea una caja de texto de tipo textarea.

ValidationSummary([Exclude property-level error])


Muestra una lista no ordenada de todos los errores que se producen al validar el formulario. Se puede validar todo o excluir los errores a nivel de las propiedades del modelo Los errores se pueden lanzar en tiempo de ejecucin con la propiedad AddModelError(campo, mensaje de error) del objeto ModelState. En caso de que el campo lo dejemos vaco estamos lanzando un error a nivel de modelo

ModelState.AddModelError("", "Prueba de un error general");

y si indicamos el campo lo hacemos a nivel de propiedad.

ModelState.AddModelError("Nombre", "El nombre no cumple con los requisitos");

Aadimos a la vista un sumario de validacin

@using(Html.BeginForm()) { @Html.ValidationSummary(false) }

El resultado

Por defecto asigna el estilo "validation-summary-errors.

ValidationMessage (s:[Nombre del campo], o:[Mensaje de error])

En caso de que no queramos que sea un sumario el que recoja todos los mensajes, si no que cada mensaje aparezca en el punto que indiquemos (normalmente a la derecha del campo), usaremos este Helper. Si no se especifica el mensaje de error, todos aquellos errores que se produzcan (o provoquemos) se visualizarn en este punto.

@Html.ValidationMessage("Nombre")

Se visualizar de la siguiente manera

Por defecto asigna el estilo field-validation-error.

Action(s: [nombre accin])


Nos permite llamar a un mtodo / accin de un controlador. Puede parecerse mucho a las vistas parciales que vimos ayer y que recordaremos luego, pero lo cierto es que mientras las vistas parciales estn pensadas para escribir bloques de cdigo, action est orientada a ejecutar el proceso completo de la accin de un controlador (que incluye la generacin del cdigo con la Vista). El resultado es una cadena de texto con todo el contenido generado.

@Html.Action("Cabecera")

ActionLink(s: [descripcin], s: [accin], s: [controlador])


Permite generar enlaces a acciones determinadas de un controlador. Por ejemplo si queremos poner un enlace a la accin Index del Home usaramos

@Html.ActionLink("Pgina principal", "Index", "Home")

Se usa en las plantillas para realizar cualquier accin con el modelo del controlador, alta, baja, edicin o borrado. Dispone de muchas sobrecargas este Helper, permitiendo desde indicar protocolor, servidor y ancla, hasta definir

los atributos HTML.

RouteLink(s: [descripcin], d: [valores ruta])


Es parecido alterior, porque genera un enlace a una ruta o una accin de un controlador. Es algo ms artesanal ya que no dispone de tantas sobrecargas y todos los valores se meten en un campo o se llama a la routa por su nombre (en caso que se haya definido previamente). Si queremos enlazar con la accin Acerca de usaramos

@Html.RouteLink("Acerca de", new { controller = "Home", action="About"})

RenderAction(s: [nombre accin])


Es idntica a Action con la diferencia de que no almacena el contenido en una cadena de texto si no que la escribe directamente al objeto Response, con lo que se visualiza por el navegador.

Si deseamos que una accin sea slo llamada desde Action o RenderAction pero no directamente como una direccin ms en el navegador podemos usar la anotacin ChildActionOnly antes de la declaracin

[ChildActionOnly] public ActionResult Cabecera() { }

Helpers con el modelo


Lo normal no ser generar todo el cdigo HTML sino que se genere a partir de un modelo, por lo tanto MVC ofrece tdo lo que hemos visto anteriormente para trabajar con modelos. Analizamos un par, pero ser lo mismo para el resto de compontes. Partimos de que la vista incluye referencia al modelo por ejemplo al Libro que contiene una propiedad ttulo

@model Proyecto.Libro

Todos los Helpers se llaman como antes pero postponiendo For al nombre, es decir TextBox pasa a ser TextBoxFor o Label pasa a ser LabelFor. Luego para hacer referencia a una propiedad del modelo se usa un alias por ejemplo m => m.propiedad o l => l.propiedad (lo que os sea ms cmodo) Si necesitamos mostrar la etiqueta, la caja de texto y la validacin

@Html.LabelFor(l => l.Titulo)

@Html.TextBoxFor(l => l.Titulo) @Html.ValidationMessageFor(l => l.Titulo)

Si lo ejecutamos lo primero que vemos es que el LabelFor de un modelo no es muy til porque es el nombre del campo. Muchas veces siglas de un campo de la base de datos, o todo en maysculas. MVC incluye data annotations en los campos lo que permite personalizar la informacin que luego se ver con estos Helpers. Por el momento slo vamos a ver el de la descripcin, pero maana nos centraremos en todo el tema de validacin, que es donde realmente se saca el potencial. Las anotaciones se ponen con corchetes antes de la definicin de la propiedad.

[Display(Name = "Ttulo del libro")] public string Titulo { get; set; }

Display permite personalizar aspectos de la visualizacin. Con Name le indicamos el nombre o label que tendr esta propiedad. El resultado es:

Personalizados
Como es lgico MVC nos permite crear nuestros propios Helpers para darle mayor potencia a stos. Se comportan como una funcin a la que se pasan parmetros si los necesita, y dentro genera el cdigo que queremos mostrar. El formato es @Helper [Nombre Funcin]( [parmetros] )

@helper BreadCumb(string[] elementos) { <div> for(int i=0; i < elementos.Count(); i++) { <span>@elementos[i]</span> if (i < elementos.Count() - 1) { <text>></text> } } </div> }

Luego para llamarla @NombreFuncin(parmetros)

@BreadCumb(new[] {"Inicio", "Administracin", "Secciones"})

El resultado es el siguiente

Es costumbre a la hora de poner los parmetros, anteponer el nombre de cada parmetro y luego : (dos puntos).

@BreadCumb(elementos: new[] {"Inicio", "Administracin", "Secciones"})

Si deseamos que es helper sea reutilizables desde cualquier vista, aadimos la carpeta App_Code a nuestro proyecto (no aparece como opcin en las carpetas de ASP.NET) y creamos el fichero BreadCumbHelpers.cshtml. Copiamos el cdigo del Helper y lo guardamos. Ahora para hacerle referencia desde la vista llamaremos al helper de la siguiente manera @[Nombre fichero (sin extensin)].[Nombre del helper o funcin]( [parmetros])

@BreadcumbHelpers.BreadCumb(elementos: new[] { "Inicio", "Administracin", "Secciones" })

Aunque puede parecer que crear un Helper es lo mismo que llamar a vistas parciales (que vimos ayer) porque ambas se usan para reaprovechar cdigo o dejarlo ms estructurado, si que es cierto que cada uno tiene su uso. Helpers personalizado est pensado para pequeos trozos de cdigo, que generan una programacin sencilla y que se comparte con diferentes vistas de tu proyecto o incluso entre varios. Partial views estn orientadas a secciones de cdigo, con el objetivo de hacer ms clara la estructura. Puede contener una programacin tan complicada como la vista que les llama.

Disponemos de dos HTMLHelpers dedicados a trabajar con Partial views (ayer usamos el comando RenderPage).

Partial(s: nombrevista)
Genera una cadena de texto con la ejecucin de la vista parcial

@Html.Partial("_Cabecera")

RenderPartial(s: nombrevista)
Es idntica a Partial con la diferencia de que no almacena el contenido en una cadena de texto si no que la escribe directamente al objeto Response, con lo que se visualiza por el navegador.

@{ Html.RenderPartial("_Cabecera"); }

Personalizados con HtmlHelper


Hay otra forma de crear Helpers personalizados en el que construimos el contenido que queremos generar. Ser una clase, con mtodos que no generan HTML directamente como una vista parcial, si no que devuelve un objeto de tipo IHtmlString. Las etiquetas se generan con TagBuildery los atributos se aaden con MergeAttribute. Un ejemplo muy til, y que encontramos en muchas pginas, es crear nuestro propio ActionLink para trabajar con imgenes.

using using using using

System.Web; System.Web.Mvc; System.Web.Mvc.Html; System.Web.Routing;

namespace _3_MVCHelpers.Helpers { public static class HtmlImageActionLinkHelper { public static IHtmlString ImageActionLink( this HtmlHelper helper, string imageUrl, string actionName, object routeValues, object htmlAttributes ) { var builder = new TagBuilder("img"); builder.MergeAttribute("src", imageUrl); builder.MergeAttributes(new RouteValueDictionary(htmlAttributes)); var link = helper.ActionLink("[replaceme]", actionName, routeValues); var html = link.ToHtmlString().Replace("[replaceme]", builder.ToString(TagRen

return new HtmlString(html); } } }

Para referenciarlo en nuestra propia vista, usaremos @Html.[Mtodo] ([Parmetros]). Si queremos aadir una imagen 012.jpg que al pulsar sobre ella vaya a la accin Index usaramos:

@Html.ImageActionLink( Url.Content("~/Fotos/012.jpg"), "Index", new { id = 5 }, new { id = "imgnb", width = "100px", height = "150px", alt = "Foto playa de Alicante" )

Como ya se coment el primer da las plantillas que usa el Visual Studio son personalizables. Se almacena por defecto en Visual Studio 2010 en la carpeta C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ItemTemplates\ CSharp\Web\MVC 3\CodeTemplates\AddView\CSHTML Si accedemos veremos 6 ficheros con la extensin tt. Lo primero que podemos pensar es en modificarlo directamente, pero esto afecta a todos los proyectos. Adems est en una carpeta que es muchas ocasiones, y por medidas de seguridad, nos pide permisos de administrador. Lo mejor es coger la carpeta CodeTemplates y copiarla a la raz de nuestra aplicacin (podemos borrar todo lo que no sea AddView\CSHTML).

El siguiente paso para poder hacer modificaciones a la plantilla es cambiar el parmetro Herramienta personalizada a las 6 plantillas. Por defecto tiene el valor TextTemplatingFileGenerator. Lo dejamos vaco.

Podemos crear nuevas plantillas y que aparezcan al crear una vista? Por supuesto. Vamos a duplicar la plantilla para a vista de listado (list.tt) para que no incluya ni dar de alta, ni poder gestionar los registros. Aunque el cdigo no es tan legible como en Razor, buscamos los bloques de HTML y vamos eliminando los contenidos que nos interesen. El objetivo es que se vea un listado con este formato. Un problema que nos podemos encontrar es que en los listados personalizados el tipo de libro aparezca como cdigo y no como descripcin. Debemos realizar unos cambios. En el controlador, hacer un include la tabla relacionada.

public ActionResult Buscar(string palabra) { IEnumerable<CSI_LIBRO> libros; using (var bd = new EntitiesBiblioteca()) { libros = bd.CSI_LIBRO.Include("CSI_TIPOLIBRO");

if (!String.IsNullOrEmpty(palabra)) { libros = libros.Where(l => l.TITULO.ToUpper().Contains(palabra.ToUppe } libros = libros.ToList(); } return View(libros); }

En la vista cambiar el campo que es clave ajena por la [tabla relacin].[campo descripcin] (slo en el caso que hayamos realizado el include porque si no es inaccesible).

<td> @Html.DisplayFor(modelItem => item.CSI_TIPOLIBRO.DESCRIPCION) </td>

ValidationSummary([Exclude property-level error])


Muestra una lista no ordenada de todos los errores que se producen al validar el formulario. Se puede validar todo o excluir los errores a nivel de las propiedades del modelo Los errores se pueden lanzar en tiempo de ejecucin con la propiedad AddModelError(campo, mensaje de error) del objeto ModelState. En caso de que el campo lo dejemos vaco estamos lanzando un error a nivel de modelo

ModelState.AddModelError("", "Prueba de un error general");

y si indicamos el campo lo hacemos a nivel de propiedad.

ModelState.AddModelError("Nombre", "El nombre no cumple con los requisitos");

Aadimos a la vista un sumario de validacin

@using(Html.BeginForm()) { @Html.ValidationSummary(false) }

El resultado

Por defecto asigna el estilo "validation-summary-errors.

ValidationMessage (s:[Nombre del campo], o:[Mensaje de error])


En caso de que no queramos que sea un sumario el que recoja todos los mensajes, si no que cada mensaje aparezca en el punto que indiquemos (normalmente a la derecha del campo), usaremos este Helper. Si no se especifica el mensaje de error, todos aquellos errores que se produzcan (o provoquemos) se visualizarn en este punto.

@Html.ValidationMessage("Nombre")

Se visualizar de la siguiente manera

Por defecto asigna el estilo field-validation-error.

Action(s: [nombre accin])


Nos permite llamar a un mtodo / accin de un controlador. Puede parecerse mucho a las vistas parciales que vimos ayer y que recordaremos luego, pero lo cierto es que mientras las vistas parciales estn pensadas para escribir bloques de cdigo, action est orientada a ejecutar el proceso completo de la accin de un controlador (que incluye la generacin del cdigo con la Vista). El resultado es una cadena de texto con todo el contenido generado.

@Html.Action("Cabecera")

ActionLink(s: [descripcin], s: [accin], s: [controlador])


Permite generar enlaces a acciones determinadas de un controlador. Por ejemplo si queremos poner un enlace a la accin Index del Home usaramos

@Html.ActionLink("Pgina principal", "Index", "Home")

Se usa en las plantillas para realizar cualquier accin con el modelo del controlador, alta, baja, edicin o borrado. Dispone de muchas sobrecargas este Helper, permitiendo desde indicar protocolor, servidor y ancla, hasta definir los atributos HTML.

RouteLink(s: [descripcin], d: [valores ruta])


Es parecido alterior, porque genera un enlace a una ruta o una accin de un controlador. Es algo ms artesanal ya que no dispone de tantas sobrecargas y todos los valores se meten en un campo o se llama a la routa por su nombre (en caso que se haya definido previamente). Si queremos enlazar con la accin Acerca de usaramos

@Html.RouteLink("Acerca de", new { controller = "Home", action="About"})

RenderAction(s: [nombre accin])


Es idntica a Action con la diferencia de que no almacena el contenido en una cadena de texto si no que la escribe directamente al objeto Response, con lo que se visualiza por el navegador.

Si deseamos que una accin sea slo llamada desde Action o RenderAction pero no directamente como una direccin ms en el navegador podemos usar la anotacin ChildActionOnly antes de la declaracin

[ChildActionOnly] public ActionResult Cabecera() { }

Helpers con el modelo


Lo normal no ser generar todo el cdigo HTML sino que se genere a partir de un modelo, por lo tanto MVC ofrece tdo lo que hemos visto anteriormente para trabajar con modelos.

Analizamos un par, pero ser lo mismo para el resto de compontes. Partimos de que la vista incluye referencia al modelo por ejemplo al Libro que contiene una propiedad ttulo

@model Proyecto.Libro

Todos los Helpers se llaman como antes pero postponiendo For al nombre, es decir TextBox pasa a ser TextBoxFor o Label pasa a ser LabelFor. Luego para hacer referencia a una propiedad del modelo se usa un alias por ejemplo m => m.propiedad o l => l.propiedad (lo que os sea ms cmodo) Si necesitamos mostrar la etiqueta, la caja de texto y la validacin

@Html.LabelFor(l => l.Titulo) @Html.TextBoxFor(l => l.Titulo) @Html.ValidationMessageFor(l => l.Titulo)

Si lo ejecutamos lo primero que vemos es que el LabelFor de un modelo no es muy til porque es el nombre del campo. Muchas veces siglas de un campo de la base de datos, o todo en maysculas. MVC incluye data annotations en los campos lo que permite personalizar la informacin que luego se ver con estos Helpers. Por el momento slo vamos a ver el de la descripcin, pero maana nos centraremos en todo el tema de validacin, que es donde realmente se saca el potencial. Las anotaciones se ponen con corchetes antes de la definicin de la propiedad.

[Display(Name = "Ttulo del libro")] public string Titulo { get; set; }

Display permite personalizar aspectos de la visualizacin. Con Name le indicamos el nombre o label que tendr esta propiedad. El resultado es:

Personalizados
Como es lgico MVC nos permite crear nuestros propios Helpers para darle mayor potencia a stos. Se comportan como una funcin a la que se pasan parmetros si los necesita, y dentro genera el cdigo que queremos mostrar. El formato es @Helper [Nombre Funcin]( [parmetros] )

@helper BreadCumb(string[] elementos) { <div> for(int i=0; i < elementos.Count(); i++) { <span>@elementos[i]</span> if (i < elementos.Count() - 1) { <text>></text> } } </div> }

Luego para llamarla @NombreFuncin(parmetros)

@BreadCumb(new[] {"Inicio", "Administracin", "Secciones"})

El resultado es el siguiente

Es costumbre a la hora de poner los parmetros, anteponer el nombre de cada parmetro y luego : (dos puntos).

@BreadCumb(elementos: new[] {"Inicio", "Administracin", "Secciones"})

Si deseamos que es helper sea reutilizables desde cualquier vista, aadimos la carpeta App_Code a nuestro proyecto (no aparece como opcin en las carpetas de ASP.NET) y creamos el fichero BreadCumbHelpers.cshtml. Copiamos el cdigo del Helper y lo guardamos. Ahora para hacerle referencia desde la vista llamaremos al helper de la siguiente manera @[Nombre fichero (sin extensin)].[Nombre del helper o funcin]( [parmetros])

@BreadcumbHelpers.BreadCumb(elementos: new[] { "Inicio", "Administracin", "Secciones" })

Aunque puede parecer que crear un Helper es lo mismo que llamar a vistas parciales (que vimos ayer) porque ambas se usan para reaprovechar cdigo o dejarlo ms estructurado, si que es cierto que cada uno tiene su uso.

Helpers personalizado est pensado para pequeos trozos de cdigo, que generan una programacin sencilla y que se comparte con diferentes vistas de tu proyecto o incluso entre varios. Partial views estn orientadas a secciones de cdigo, con el objetivo de hacer ms clara la estructura. Puede contener una programacin tan complicada como la vista que les llama.

Disponemos de dos HTMLHelpers dedicados a trabajar con Partial views (ayer usamos el comando RenderPage).

Partial(s: nombrevista)
Genera una cadena de texto con la ejecucin de la vista parcial

@Html.Partial("_Cabecera")

RenderPartial(s: nombrevista)
Es idntica a Partial con la diferencia de que no almacena el contenido en una cadena de texto si no que la escribe directamente al objeto Response, con lo que se visualiza por el navegador.

@{ Html.RenderPartial("_Cabecera"); }

Personalizados con HtmlHelper


Hay otra forma de crear Helpers personalizados en el que construimos el contenido que queremos generar. Ser una clase, con mtodos que no generan HTML directamente como una vista parcial, si no que devuelve un objeto de tipo IHtmlString. Las etiquetas se generan con TagBuildery los atributos se aaden con MergeAttribute. Un ejemplo muy til, y que encontramos en muchas pginas, es crear nuestro propio ActionLink para trabajar con imgenes.

using using using using

System.Web; System.Web.Mvc; System.Web.Mvc.Html; System.Web.Routing;

namespace _3_MVCHelpers.Helpers { public static class HtmlImageActionLinkHelper { public static IHtmlString ImageActionLink( this HtmlHelper helper, string imageUrl, string actionName, object routeValues,

object htmlAttributes ) {

var builder = new TagBuilder("img"); builder.MergeAttribute("src", imageUrl); builder.MergeAttributes(new RouteValueDictionary(htmlAttributes)); var link = helper.ActionLink("[replaceme]", actionName, routeValues); var html = link.ToHtmlString().Replace("[replaceme]", builder.ToString(TagRen return new HtmlString(html); } } }

Para referenciarlo en nuestra propia vista, usaremos @Html.[Mtodo] ([Parmetros]). Si queremos aadir una imagen 012.jpg que al pulsar sobre ella vaya a la accin Index usaramos:

@Html.ImageActionLink( Url.Content("~/Fotos/012.jpg"), "Index", new { id = 5 }, new { id = "imgnb", width = "100px", height = "150px", alt = "Foto playa de Alicante" )

DIRECCIN POSTAL Universidad de Alicante Carretera de San Vicente del Raspeig s/n 03690 San Vicente del Raspeig Alicante (Spain) Tel: (+34) 96 590 3400 Fax: (+34) 96 590 3464

Vous aimerez peut-être aussi