Академический Документы
Профессиональный Документы
Культура Документы
ASP.NET MVC 4
ELEMENTOS GRFICOS
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es/
GUA DE ESTILO
Con el objetivo de conseguir un diseo de aplicaciones comn, se ha preparado una gua de estilo con los elementos bsicos para el desarrollo de aplicaciones. Actualmente slo est disponible en nuestras mquinas de desarrollo y lo podemos encontrar en nuestra carpeta compartida del aula. El ejemplo de un listado con su gestin lo podemos ver en la imagen siguiente
La gua dispone de documentacin de los elementos grficos ms comunes; avisos, botones, calendarios, listados, etc. Con el desarrollo de nuevas aplicaciones en este entorno se irn incorporando nuevas funcionalidades o elementos.
SEGUIDAD
Se han incorporado ejemplos de identificacin con LDAP y en breve como integrarlo con el Sistema de Identifiacin nico (CAS). Se apoya en las libreras desarrolladas en el Servicio de Informtica. No slo permite identificarse sino que permite personalizar a dnde puede acceder ese usuario o el rol al que pertenece. Igualmente se ha implementado un sistema para obligar a la identificacin en entornos SSL. Hasta el momento se dejaba al programador esta tarea, que en muchas ocasiones se nos olvidaba o no le dbamos poca importancia. Ahora est completamente integrado con lo que su uso se hace obligatorio a la hora de identificarse.
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
DISEO SENSIBLE
Cada vez es ms frecuente encontrar Webs que se adaptan al dispositivo que se conectan sin tener que crear plantillas diferentes para cada uno, a eso se le llama diseo sensible (responsive design). Nuestra plantilla se ve correctamente en un navegador de escritorio
Como en un mvil
Cada vez es ms frecuente el acceso a nuestra web desde dispositivos mviles o tabletas. Permitir el acceso y uso de nuestras aplicaciones desde estos dispositivos las hacen ms atractivas.
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
RAZOR EN DETALLE
MODELO
En la mayora de los casos la vista trabaja con los datos de un modelo. Por eso nos podemos encontrar con dos casos, que le enviemos un nico registro (por ejemplo para operaciones de creacin o edicin) o con un conjunto de datos (por ejemplo listados).
Luego para usarlo dentro del cdigo haremos referencia directamente al objeto model
@Html.EditorFor(model => model.NOMBRE_ES)
Layout
Es el equivalente a las MasterPages en WebPages, es decir la plantilla comn para todas las pginas de nuestro sitio. Por defecto al crear un proyecto MVC nos crea en la carpeta Views > Shared el fichero _Layout.cshtml. Esta pgina es la plantilla que usar el asistente de las vistas cuando no seleccionamos ninguna. Se puede seleccionar cualquier otra en el momento que creamos la vista
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
o accediendo al cdigo de la vista generado y aadido la lnea Layout = Fichero con la plantilla para la vista
@{ Layout = "~/Views/Shared/_Layout.cshtml"; }
@RenderBody()
Se utiliza en _layout.cshtml para indicar que en ese punto se incluir el cdigo generado por la vista. Todos los layouts deben incluirla. En caso de no hacerlo obtendremos el siguiente mensaje de error.
Error de servidor en la aplicacin '/'. No se ha llamado al mtodo "RenderBody" para la pgina de diseo "~/Views/Shared/_layout.cshtml".
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
@section
Definimos una seccin de cdigo Razor / HTML que se insertar en el layout en caso de que se llame a @rendersection con el nombre de la seccin que hayamos declarado.
@section NombreSeccin { }
Si queremos definir una seccin cabecera, en cada vista la definiramos del siguiente modo.
@section cabecera { <h1>Ejemplo de seccin</h1> }
@RenderSection
Incluimos en nuestra plantilla secciones o bloques de cdigo Razor / HTML que se ha definido en la vista. Podemos indicar adems si es obligatorio o no definirla.
@RenderSection("NombreSeccin ", required: false / true)
Por defecto toma el valor true, con lo que en caso de que no la incluyamos en nuestra vista, dar un mensaje de error.
Seccin no definida: "cabecera". Descripcin: Excepcin no controlada al ejecutar la solicitud Web actual. Revise el seguimiento de la pila para obtener ms informacin acerca del error y dnde se origin en el cdigo.
@RenderSection("cabecera", required:false)
IsSectionDefined
Por ltimo para controlar si se ha definido la seccin, disponemos de la funcin IsSectionDefined(). Siguiendo con el ejemplo de la cabecera podramos comprobar si se ha definido para darle un formato y sino le damos otro formato.
@if (IsSectionDefined("cabecera")) { <div id="title"> @RenderSection("cabecera") </div> } else { <div id="titledefalt"><h1 class="generico">Ttulo genrico</h1></div> }
No podramos afimar si est llamando a @model.foto y luego incorpora la extensin .jpg o que interprete que .jpg es una propiedad de @model.foto. Deberamos utilizar
<img src="images/"@(model.foto).jpg" />
@:
Aunque ya lo vimos ayer, lo vuelvo a remarcar. Aquel texto HTML que no incluya etiquetas puede provocar que se interprete como cdigo Razor.
<span> @if(true){ La hora es: @DateTime.Now } else { Aqu no se debera acceder nunca } </span>
No sabe si es cdigo HTML o cdigo C#. Para definrselo anteponemos @: (si slo es una lnea) para decirle que es HTML
<span> @if(true){ @:La hora es: @DateTime.Now } else { @:Aqu no se debera acceder nunca } </span>
Html.Raw
Escribe el contenido que le pasemos sin codificar (que es lo que hace por defecto ASP.NET MVC 3). Puede que en ocasiones necesitemos que sea as (por ejemplo porque incluye etiquetas de formato), aunque debemos tener mucho cuidado con el contendido para que no nos produzcan XSS Injection.
<h2>@Html.Raw(ViewBag.Message)</h2>
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
Partial Views
Como conocemos las vistas hasta ahora genera una pgina web en cada llamada. Con un layout por defecto o personalizado, pasando por el cdigo generado por la vista y terminando con secciones opcionales o no. Esto no lo hace muy complicado de mantener y sobre todo poco flexible. Por eso existen las vistas parciales que permiten dividir la pgina en bloques ms pequeos lo que las hace ms fcil de gestionar. Puede ser muy til en llamada AJAX porque el cdigo generado es el que le indiquemos en la vista parcial sin elementos como layout que se supone que se ha llamada anteriormente desde una vista. Con un ejemplo lo vamos a ver muy claro. Queremos hacer la suma de dos nmeros es un mtodo del controlador Home. Pasamos dos parmetros y cambiamos return View(); por return PartialView();
public ActionResult Suma(int numero1, int numero2) { ViewBag.Suma = numero1 + numero2; return PartialView(); }
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
pero como es lgico el propsito no era ste. Nosotros queremos incluirlo dentro de otra vista y lo vamos a hacer con AJAX, es decir se cargar una vista inicial y ante un evento modificaremos el contenido de algn elemento de la vista inicial con el contenido de la vista parcial. Incluimos el siguiente cdigo en algn mtodo de home
La suma de 5 y 7 es: <span id="operacion"></span> <script type="text/javascript"> $(function(){ $("#operacion").load("/home/Suma?numero1=5&numero2=7"); }); </script>
La primera lnea pone un texto y prepara una etiqueta donde luego mostrar el resultado. Las siguientes lneas son javascript y JQuery. Esta librera est muy integrada en Visual Studio con lo que debemos aprovechar que la disponemos. Lo que hace es llamar a nuestro controlador con load y poner el resultado en aquella etiqueta que tenga como id operacion ($(#idetiqueta)). Visualmente vemos el resultado de la operacin, pero internamente ha hecho una segunda llamada para obtener el resultado de la suma y luego ha modificado el contenido de la etiqueta. No es obligatorio llamarlo desde javascript y con AJAX, podemos llamarlo desde nuestras propias vistas. El ejemplo de ayer que mostrbamos un listado de alumnos. Usamos el siguiente cdigo
<p>Listado de alumnos</p> <ul> @foreach (var item in Model) { <li>@item.Nombre @item.Apellidos</li> } </ul>
Si el formato de la ficha del alumno fuera muy amplia, sera una buena solucin convertirla en una vista parcial y llamarla desde nuestra propia vista
<p>Listado de libros (Vistas parciales)</p> @foreach (var item in Model) { @RenderPage("~/Views/Home/Formato.cshtml", new {alumno = item}); }
Para recoger los parmetros tenemos que usar el objeto Page y como propiedad lo que hayamos pasado, en este caso libro y trabaramos con las propiedades de ste como si fuera el modelo.
@{ var Model = Page.alumno; } <div> <strong>Nombre: </strong> @Model.Nombre </div> <div style="margin-bottom: 20px;"> <strong>Apellidos: </strong> @Model.Apellidos </div>
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
En este segundo caso no se hace una llamada por cada libro, ya que se hace internamente antes de devolver la pgina completa.
HELPERS
Los Helpers podramos entenderlo como una forma de facilitar de reutilizar cdigo que escribimos en muchas ocasiones. MVC nos ofrece de dos tipos:
HTMLHelpers orientados a escribir cdigo HTML. La mayora de mtodos que nos ofrece son para trabajar con formularios, simplificando y unificando enormemente este proceso. URLHelpers orientada a simplificar el trabajo con direcciones y conversiones de caracteres.
En el da de hoy nos centraremos en los segundos porque son muy pocos y los necesitamos para poder crear nuestro primer layout / plantilla.
URLHelper
Para poder usar este Helper dentro del motor Razor antepondremos @Url al mtodo que queramos llamar. Por ejemplo si queremos poner la ruta de nuestro fichero css, en el layout por defecto hace uso del mtodo Content de URLHelper.
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
La integracin es muy sencilla porque no debemos hacer ninguna referencia externa y dispone de intellisense lo que facilita su escritura. Los 4 mtodos que lo forman son
Action(s:action, s:controller, )
Genera la direccin completa de la llamada a un mtodo / accin de un controlador. Por ejemplo si queremos crear un enlace a Acerca de, podramos usar el siguiente cdigo HTML
<a href="@Url.Action("About", "Home")">Acerca de</a>
Si queremos hacer una llamada a un mtodo Buscar al que le pasemos el trmino de bsqueda, incluiramos un tercer campo, con los parmetros que queramos personalizar.
<a href="@Url.Action("Buscar", "Home", new { busqueda = "Servicio de Informtica" })">Buscar por "Servicio de Informtica"</a>
10
Content(s:path)
Convierte una direccin virtual / relativa en su correspondiente direccin absoluta de la aplicacin. Es muy til cuando hacemos referencia a ficheros como hojas de estilo o javascript
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
Encode(s:url)
Codifica los caracteres especiales de una URL por sus equivalentes caracteres estndar. Se usa para evitar problemas con ciertos navegadores que no interpretan los caracteres especiales. En el ejemplo anterior el envo de Servicio de Informtica sera uno de los casos que nos podran dar errores por os espacios y acento.
<a href="@Url.Action("Buscar", "Home", new { busqueda = Url.Encode("Servicio de Informtica") })">Buscar por "Servicio de Informtica"</a>
RouteUrl(s:route)
Muy parecido al primero pero todo en uno, es decir pasamos los parmetros que queramos en un nico parmetro, de la siguiente manera new { Controller = , Action = , } La misma llamada Acerca de pero con RouteUrl sera.
<a href="@Url.RouteUrl(new {Controller = "Home", Action = "About"})">Acerca de</a>
Maana nos centraremos en los HTMLHelpers y veremos como crear los nuestros propios.
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.
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
11
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.
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", "Alumno", FormMethod.Get)
Y generara
<form action="/Alumno/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", "Alumno", 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", "Alumno", FormMethod.Get, new {id="fTest", @class="formulario-ua"})
En caso de que no usemos using en la declaracin de beginform deberemos usar endform para indicar donde acaba.
@{ Html.BeginForm("Create", "Alumno", FormMethod.Get, new {id = "fTest", @class = "formulario-ua"}); } @{ 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
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
12
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", "Alumno", FormMethod.Get, new {id = "fTest", @class = "formularioua"})) { @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.
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
13
ListBox(s:name, list:selectlistitems)
Genera una lista de valores en la que podemos seleccionar ms de un elemento.
@using(Html.BeginForm("Create", "Alumno", FormMethod.Get, new {id = "fTest", @class = "formularioua"})) { @Html.Label("Unidad") @Html.ListBox("Unidad", new MultiSelectList(new[] {"Servicio de Informtica", "Seleccin y Formacin", "Servicio de Personal"})) }
Genera
TextArea(s:name, s:value)
Crea una caja de texto de tipo textarea.
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
14
El resultado
15
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.
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
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
16
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
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 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.
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
17
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" })
Como resumen de los helpers locales: Se declaran en la propia vista en un bloque @helper No pueden devuelven ningn tipo de dato. En realidad devuelven un HelperResult pero para nosotros es totalmente transparente. Su cdigo se escribe directamente en la vista Sirven exclusivamente para generar HTML (a diferencia de los helpers locales normales que podan devolver cualquier tipo de dato).
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(TagRenderMode.SelfClosing)); return new HtmlString(html); } } }
18
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 resumen de los helpers globales: Mtodo de extensin de la clase HtmlHelper. Devuelve una instancia de HtmlString. o En cualquier caso, no es obligatorio que un helper devuelve siempre cdigo HTML, tambin podra devolver cualquier otro tipo de datos, por ejemplo un bool o simplemente no devolver nada (void). Adems incluso podra devolver directamente un string y entonces Razor codificara en HTML la salida (con HtmlString, Razor confa en los helpers y no codifica en HTML la salida). o Utilizar la clase TagBuilder para construir el DOM. Accesible por cualquier vista que importe el espacio de nombres donde est declarado el helper (tambin pueden incluir el espacio de nombres en el fichero Views/Web.config y estar automticamente disponibles para todas las vistas).
Seleccionando otro idioma veremos que los elementos comunes han cambiado.
La lgica se gestiona desde Application_AcquireRequestState en el fichero Global.asax.cs. Analiza si ya la tenemos guardada en Session[idioma]. En caso de que no la encuentre la extrae de la configuracin del navegador.
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
19
Dentro de la carpeta Controller disponemos de la lgica bsica para cambiar de idioma y retornar a la pgina que nos llam.
RECURSOS
El elemento base para gestionar las traducciones son los recursos. Una buena prctica es crearnos una carpeta Resources y meter todos aquellos ficheros que necesitemos. Se pueden crear a nivel de controlador o modelo o a nivel de aplicacin si nuestro proyecto es muy bsico. Sobre el proyectos pulsamos botn derecho Agregar > Nueva carpeta y le ponemos el nombre Resources. Ahora sobre esta nueva carpeta Agregar > Nuevo elemento y seleccionamos (o filtramos) Archivo de recursos. Le llamamos modelos.resx
Es importante que marquemos el fichero como pblico para que se pueda acceder desde el resto de los elementos de MVC
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
20
Para crear la versin de recursos para otro idioma, copiamos y pegamos el que usemos de base y luego le aadimo .[dos digitos del idioma] antes de la extensin del fichero. Es nuestro caso para crear el fichero de recursos en ingls renombraramos copia de modelos.resx por modelo.en.resx y traduciramos los valores de cada una de las etiquetas.
VISTAS
La manera ms cmoda de pasar textos traducidos a las vistas, en caso de que sean pocos, es usar el controlador y el objeto ViewBag. Para acceder a un recurso escribimos el [nombre carpeta de recursos].[ nombre recurso (sin extensin].etiqueta.
ViewBag.Titulo = Resources.modelos.tituloLabel;
Si la vista contiene muchos elementos a traducir, lo ms sencillo es crear dos versiones de la vista de la misma manera que lo hemos hecho con el fichero de recursos. Cogemos la vista base index.cshtml la copiamos y la pegamos y renombramos por index.en.cshml. Hacemos los cambios que corresponda
Creamos una clase para gestionar los idiomas CultureHelper. La variable Cultures almacena los idiomas con los que trabajemos. El primero de ellos ser el que se usar por defecto en caso de que detectemos otro que no se corresponda con nuestro listado.
using System; using System.Collections.Generic; using System.Linq; namespace _3_MvcGlobalization.Helpers { public static class CultureHelper { // Include ONLY cultures you are implementing as views private static readonly Dictionary<String, bool> Cultures = new Dictionary<string, bool> { {"es", true}, // first culture is the DEFAULT {"en", true}, {"ca", true} };
/// <summary> /// Returns a valid culture name based on "name" parameter. If "name" is not valid, it returns the default culture "en-US" /// </summary> /// <param name="name">Culture's name (e.g. en-US)</param> public static string GetValidCulture(string name) { if (string.IsNullOrEmpty(name)) return GetDefaultCulture(); // return Default culture if (Cultures.ContainsKey(name)) return name;
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
21
/// <summary> /// Returns default culture name which is the first name decalared (e.g. en-US) /// </summary> /// <returns></returns> public static string GetDefaultCulture() { return Cultures.Keys.ElementAt(0); // return Default culture }
/// <summary> /// Returns "true" if view is implemented separatley, and "false" if not. /// For example, if "es-CL" is true, then separate views must exist e.g. Index.es-cl.cshtml, About.es-cl.cshtml /// </summary> /// <param name="name">Culture's name</param> /// <returns></returns> public static bool IsViewSeparate(string name) { if (Cultures.ContainsKey(name)) return Cultures[name]; return false; } } }
El siguiente paso es crear nuestro propio controlador que detectar el idioma y personalizar la vista. Requerimos hacer uso de dos mtodos de la clase Controller: ExecuteCore y OnActionExecuted. El primero normaliza el idioma, lo almacena en una variable sesin y establece CurrentCulture. En Session[idioma] vamos a almacenar el idioma que se haya detectado o el que se seleccione (lo veremos luego). De esa manera lo podremos usar en cualquier vista o controlador. El segundo establece la vista que debe abrir el controlador dependiendo del idioma que se haya seleccionado.
using using using using System.Globalization; System.Threading; System.Web.Mvc; _3_MvcGlobalization.Helpers;
namespace _3_MvcGlobalization.Controllers { public class UaController : Controller { protected override void OnActionExecuted(ActionExecutedContext filterContext) { // Detectamos si llamamos desde una vista var view = filterContext.Result as ViewResultBase; Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
22
protected override void ExecuteCore() { var idioma = Session["idioma"]; string cultureName; if (idioma != null) cultureName = idioma.ToString(); else { cultureName = (Request.UserLanguages == null ? CultureHelper.GetDefaultCulture() : Request.UserLanguages[0]); if (cultureName.IndexOf("-") > 0) cultureName = cultureName.Substring(0, cultureName.IndexOf("-")); Session["idioma"] = cultureName; } // Normalizamos var normalizedCultureName = CultureHelper.GetValidCulture(cultureName); if (normalizedCultureName != cultureName) { cultureName = normalizedCultureName; Session["idioma"] = cultureName; } // Actualizamos el idioma Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName); Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultureName); base.ExecuteCore(); } Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
23
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
24
PLANTILLA
Por defecto la plantilla que se usa es la que se configure en /Views/ _ViewStart.cshtml. Por seguir con este criterio, si modificamos este fichero y usamos la variable Session[idioma] tendremos la plantilla que se debe usar.
@{ Layout = "~/Views/Shared/_Layout." + @Session["idioma"] + ".cshtml"; }
En clase lo optimizaremos para que no se produzcan errores cuando no est definida esta variable.
CAMBIAR DE IDIOMA
Nuestra plantilla permite cambiar el icioma
public ActionResult ChangeLanguage(string language) { Session["idioma"] = language; if (Request.UrlReferrer != null) return Redirect(Request.UrlReferrer.ToString()); return Redirect("Index"); } [ @Html.ActionLink("English", "ChangeLanguage", "Home", new { language = "en" }, null) ] [ @Html.ActionLink("Espaol", "ChangeLanguage", "Home", new { language = "es" }, null) ] [ @Html.ActionLink("Valenci", "ChangeLanguage", "Home", new { language = "ca" }, null) ]
En caso de que nos enven un idioma que no se corresponda con el listado admitido, no habr problemas porque en la siguiente llamada a Index (o la pgina desde donde se llam) se detectar que no se corresponde con uno de los admitidos y se asignar el que tengamos por defecto.
MODELO
Siguiendo el ejemplo del libro de antes, si queremos que la descripcin del ttulo salga del fichero de recursos remplazamos
[Display(Name = "Ttulo del libro")] public string Titulo { get; set; }
por
[Display(Name = "tituloLabel", ResourceType = typeof(Resources.modelos))] public string Titulo { get; set; }
En caso de que nos de un error de que no se encuentra un recurso pblico con ese nombre, recordar lo de marcar Public en el fichero de recursos.
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
25
BOOTSTRAP
Es un framework diseado para simplificar el proceso de creacin de diseos web. Para ello nos ofrece una serie de plantillas CSS y de ficheros JavaScript, los cuales nos permiten conseguir: Interfaces que funcionen de manera brillante en los navegadores actuales, y correcta en los no tan actuales. Un diseo que pueda ser visualizado de forma correcta en distintos dispositivos y a distintas escalas y resoluciones. Una mejor integracin con tus las libreras que sueles usar habitualmente, como por ejemplo jQuery. Un diseo slido basado en herramientas actuales y potentes como LESS o estndares como CSS3/HTML5
Vamos a trabajar durante el curso con la versin 2.3.2 aunque ya est disponible la versin 3. En el momento que sea ms estable y la mayora de los componentes que usamos sean compatibles haremos el salto a la nueva versin. Nada mejor que acceder a su pgina web y ver lo que nos ofrece http://getbootstrap.com/2.3.2/ De todos los elementos nos vamos a centrar en los bsicos para comenzar a trabajar: Grid (http://getbootstrap.com/2.3.2/scaffolding.html#fluidGridSystem) Botones (http://getbootstrap.com/2.3.2/base-css.html#buttons) Formularios (http://getbootstrap.com/2.3.2/base-css.html#forms) Iconos (http://getbootstrap.com/2.3.2/base-css.html#icons)
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
26
JQUERY
jQuery es una biblioteca de JavaScript, que permite simplificar la manera de interactuar con los documentos HTML, manipular el rbol DOM, manejar eventos, desarrollar animaciones (FLV) y agregar interaccin con la tcnica AJAX a pginas web. Es la biblioteca de JavaScript ms utilizada. ASP.NET MVC usa esta librera de base (la podemos encontrar en la carpeta Scripts) y la mayora de los plugins que encontramos por Internet hace uso de ella. La plantilla que tiene por defecto ASP.NET MVC la incluye con lo que podemos utilizarla en nuestras vistas sin ningn problema. La tarea ms comn en JQuery es acceder a algn elemento de nuestra pgina modificar sus propiedades o contenido y que se actualice antes de que se visualice la pgina al usuario. Nos vamos a centrar en estos puntos y cada da iremos incorporando nuevas caractersticas.
SELECTORES
Jquery dispone de varios mtodos para acceder a los elementos de nuestra pgina. Vamos a analizar los ms comunes. Todos ellos utilizan la funcin $([selector]). Si nunca se ha programado con JQuery o Mootools nos llamar la atencin que se use el $ como funcin para acceder a los elementos de nuestra pgina. En caso de que trabajemos con JQuery y Mootools, y hagamos referencia a ambas libreras desde nuestras pginas, se producir un conflicto por la funcin $ que ambas usan. Para solucionarlo JQuery ofrece una solucin muy sencilla. Incluimos la instruccin jQuery.noConflict(); para indicar que desde este momento para hacer uso del selector en JQuery vamos a utilizar jQuery ([selector]) en vez de $([selector]). De esa manera ya no interfiere con Mootools que lo sigue utilizando sin problemas. Vamos a analizar los selectores ms comunes
$(#id)
Seleccionamos un elemento HTML por el id que tenga. Es muy normal usarlo en elementos muy comunes de nuestra pgina cabecera, cuerpo, noticias o pie, aunque si somos cuidadosos con los ids, podemos usarlo en cualquier elemento que queramos. Por ejemplo si tenemos una capa div con id igual a capa_1
<div id="capa_1"></div>
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
27
Ahora podramos hacer cualquier operacin con este elemento, que es un objeto que dispone de mtodos / funciones que iremos viendo.
$(elemento)
En ocasiones nos interesa que todos los elementos HTML de un tipo (por ejemplo los enlaces) cambien alguna propiedad que no es accesible (el ejemplo ms claro es que se abran en un nueva ventana). Tenemos un listado de enlaces
<div id="capa_2"> <a href="1">Enlace <a href="2">Enlace <a href="3">Enlace <a href="4">Enlace </div> 1</a><br 2</a><br 3</a><br 4</a><br /> /> /> />
Un error comn cuando comenzamos con JQuery es que creemos que el elemento el es el propio elemento HTML y que por tanto accedo a sus atributos con el.target = "_blank";. Si lo probis veris que no es as, porque el es un objeto JQuery y no un enlace. Debemos usar los mtodos que nos ofrece JQuery para estas tareas.
$(.clase) o $(elemento.clase)
Un paso ms en la seleccin es que no accedamos a elementos tan genricos si no a aquellos que nosotros marquemos con un estilo determinado. El ejemplo anterior sera mejor si slo lo aplicramos a aquellos enlaces que pertenezcan a la clase externo. Modificamos el listado anterior para indicar que dos son externos y otros dos no.
<div id="capa_2"> <a class="externo" <a href="2">Enlace <a class="externo" <a href="4">Enlace </div> href="1">Enlace 1</a><br /> 2</a><br /> href="3">Enlace 3</a><br /> 4</a><br />
Para acceder a estos dos enlaces no podemos usar el genrico de elementos porque cogeramos los 4, usamos:
var els = $("a.externo");
o en caso de que slo se use esta clase con enlaces y no haya confusin con otros elementos
var els = $(".externo"); Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
28
Otro ejemplo muy comn es crearnos un estilo obligatorio que realice determinadas operaciones sobre los elementos (cambiar color, poner en negrita, aadir un asterisco para indicar que es obligatorio, etc.).
var els = $(".obligatorio");
Hijos o descendente
Ahora es el momento de combinar selectores
$(#cabecera a)
Selecciona todos los enlaces que hay dentro de el elemento con id igual a cabecera da lo mismo que estn en el siguiente nivel de cabecera o dentro de otros elementos. En
<div id="cabecera" style="margin-top: 20px;"> <a href="1">Enlace 1</a><br /> <a href="2">Enlace 2</a><br /> <div id="subcabecera" style="margin-top: 10px;"> <a href="3">Enlace 3</a><br /> <a href="4">Enlace 4</a><br /> </div> </div>
$(#cabecera > a)
Si solo queremos modificar los 2 enlaces hijo y descartar otros descendientes que pertenecen a otro elemento.
var els = $("#cabecera > a"); els.each(function () { var el = $(this); el.attr("style", "color: red"); });
Slo cambia el color a los dos primeros enlaces que son hijos directos de cabecera.
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
29
FUNCIONES
Un problema que nos podemos encontrar con JavaScript es el momento de inicializar los elementos de HTML porque hasta que no se acaba el cdigo, no tenemos a nuestra disposicin a todos los elementos. Una buena costumbre es poner al final del HTML todos los ficheros que hacen referencia a JavaScript. La razn principal es que la persona ya puede comenzar a visualizar la pgina en ese momento y no debe esperar a que se carguen todos los ficheros JavaScript que en ocasiones, si hacen referencia a direcciones externas, pueden producir un retardo molesto. Adems de esta tcnica que usaremos en nuestras plantillas, jQuery tiene dos mtodos de ejecutar cdigo en el momento que el Modelo de Objetos del Documento (DOM) est disponible:
$(document).ready
http://api.jquery.com/ready/ Le indicamos la funcin que se ejecutar en el momento de estar listo el DOM. En el siguiente ejemplo actualizar el contenido de un elemento con id igual a capa_1. Independiente de que este cdigo est al principio o al final no dar error porque no se ejecuta en el momento de leerse el JavaScript.
$(document).ready(function () { var el = $("#capa_1"); el.html("Aadimos un texto"); });
$(function () { });
Tiene el mismo comportamiento que la anterior. Cuando se pasa una funcin como primer parmetro, le indicas a jQuery que lo ejecute cuando est disponible el DOM. El ejemplo anterior sera:
$(function () { var el = $("#capa_1"); el.html("Aadimos un texto"); });
Arrays
Aplicar una funcin a un array es una tarea muy comn. Lo hemos visto cambiando el comportamiento de los enlaces. Se usa mucho para asignar eventos que no por accesibilidad no estn permitidos dentro del cdigo HTML. Usamos el comando each (http://api.jquery.com/jQuery.each/) que le pasamos una funcin como parmetro y dentro de sta podemos acceder a cada elemento con $(this).
arrayElementos.each(function () { var el = $(this); Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
30
.children()
Obtiene los hijos inmediatos nicos de un elemento. En la siguiente figura vemos una capa div con tres enlaces dentro. Si tenemos seleccionada la capa siv y solicitamos los hijos obtenemos un array de enlaces, que podemos gestionar facilmente con each.
CONTENIDO
Disponemos dos formas muy sencillas para modificar el contenido de un elemento.
html
http://api.jquery.com/html/ Nos deja remplazar el cdigo o texto que hay en ese el elemento por el que le indiquemos. Permite cdigo con etiquetas HTML.
el.html("Aadimos un texto en <strong>negrita</strong>");
31
text
http://api.jquery.com/text/ Parecido al anterior pero slo para remplazar con texto sin formato. Ambas funciones tambin permite leer el contenido si no se le enva ningn parmetro. En el caso de text, si lo que lee tiene etiquetas HTML las elimina.
var texto = el.text();
val
http://api.jquery.com/val/ Devuelve o asigna el valor a un campo de un formulario.
var contenido = el.val(); el.val(contenido);
append
http://api.jquery.com/append/ En caso de que el elemento ya tenga contenido, no lo remplaza, lo escribe detrs del contenido actual.
prepend
http://api.jquery.com/prepend/ En caso de que el elemento ya tenga contenido, no lo remplaza, lo escribe antes del contenido actual.
load
http://api.jquery.com/load/ Podemos cargar el contenido desde otra pgina. Lo normal, y como ya hicimos el 2 da es que lo hagamos desde una accin de nuestros controladores. Por ejemplo si queremos cargar el contenido de la accin Contenido de nuestro controlador Home, ejecutaramos:
el.load("/Home/Contenido");
El resultado es
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
32
.css()
Consultamos o modificamos los estilos del elemento. Por ejemplo si queremos cambiar el color de un texto a rojo para resaltarlo
PROPIEDADES
attr
http://api.jquery.com/attr/ En ocasiones lo que nos interesa no es aadir contenido si no modificar alguna propiedad, por ejemplo el color o poner en negrita por si queremos destacar algo.
el.attr("style", "color: red; font-weight: bold;");
prop
http://api.jquery.com/prop/ Aunque en muchas ocasiones nos pueda llevar a confusin con la function attr, prop est orientada a modificar propiedades de los objetos como puedes ser checked, disabled, multiple, readOnly, etc., mientras que attr a modificar atributos como class, href, label, src, title, etc. Por ejemplo si queremos consultar o modificar el estado de un checkbox $(elemento).prop("checked"); Y $(elemento).prop("checked", true);
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
33
EJERCICIOS
Reemplazar contenido de un div con lo insertado en un textarea Aadir el contenido de un textarea a un div Chequear todos los checkbox que hay dentro de una capa div Igualar altura de todas las columnas que haya dentro de un capa div. Usaremos el mtodo height() Aadir un icono delante de todos los enlaces que tengan la clase vineta
ANUNCIOS
Crear un helper para poder valorar un anuncio Crear un helper para poder realizar comentarios
CATALOGADOR
Crear helpers para los elementos comunes o Descripcin de un catalogador o Descripcin de una seccin
Andrs Valls Botella | Analista | Desarrollos propios Servicio de Informtica | Universidad de Alicante Campus de Sant Vicent del Raspeig | 03690 | Espaa http://si.ua.es/es
34