El pasado sábado 29 de marzo, tuve el placer de participar junto con “N” expertos en diferentes áreas de Azure en un evento celebrado simultáneamente a nivel mundial. Mi participación, además de a nivel de ayuda en la organización, se extendió a dar una sesión junto al gran Rafa Serna “Conectividad multiplataforma a través de servicios móviles” en la que tratamos sobre Azure Mobile Services pero únicamente desde la perspectica de Windows 8 y Windows Phone que es a lo que se nos tiene acostumbrados, sino que además, mostramos un ejemplo HTML con Angular.js, un ejemplo haciendo uso de la API REST en una aplicación desarrollada en Delphi y también un ejemplo de su uso en Android. Con todo ello, tratamos de mostrar a los asistentes la facilidad de uso de Azure Mobile Services desde cualquier tecnología. Además, nos adentramos en profundizar en algunas características como:
Uso de servicios de autenticación como Facebook, Google, MS Account, …
Uso de los scripts de las tablas de Azure o “triggers” como los denomino yo (Insert, Update, Delete, Read) para introducir nuevos datos como el usuario.
Uso de scripts personalizados que intercepten el verbo de la petición (POST, PUT, GET, DELETE,…) para realizar operaciones extras.
Uso de API REST para trabajar con los datos de Azure Mobile Services
Todos estos contenidos los condensamos y comprimimos en una sesión de 45 minutos que espero que los asistentes hayan disfrutado.
Los asistentes pudieron participar en un hands on labs «global», formando parte de una granja de cómputo global para ayudar a realizar una investigación sobre <a href=»http://global.windowsazurebootcamp.com/charity/» target=»_new»>el diagnóstico temprano de la diabetes de Tipo 2.</a>. Las instrucciones de participación las podéis encontrar en este enlace.
TenerifeDev fuera de la isla
Además, quiero destacar la participación en el GWAB (Global Windows Azure Bootcamp) de otros dos coordinadores de TenerifeDev (#canarianpower), Alberto Díaz que se encargó de dinaminzar la zona “Azk the Experts” además de participar en la “Keynote” y David Rodríguez que participó en la Keynote, se encargó de gestionar nuestra participación el en Lab mundial sobre diabetes y también tuvo su sesión “Caso éxito: DNN Cloud Services – Under the Hood en la que nos ilustró sobre el servicio de DNN Evoq en la Nube”.
Hoy quiero compartir con todos vosotros un nuevo reconocimiento que me ha llegado, y es que el pasado martes (01-04-2014) Microsoft me ha nombrado ¡¡MVP en Client Development!! Ha sido una enorme y grata sorpresa pues para nada me esperaba esto. Es un gran honor y espero ser merecedor, al menos trabajaré para que así sea ya que por mi parte continuaré participando en todos aquellos eventos en los que me permitan estar, seguiré tratando de compartir con todos vosotros lo que vaya aprendiendo en mi día a día y seguiré promoviendo aquellas tecnologías que me parezcan útiles y productivas, al menos desde mi punto de vista.
Agradecimientos
Como siempre, hay que dar los agradecimientos pertinentes a todas las personas que han sido referencia para mi y que me han guiado en este camino en mayor o menor medida y, cómo no, hay que empezar por el gran maestro Alberto Díaz que desde hace ya mucho tiempo es mi gran referente y un gran amigo que me ha ido guiando para que pueda crecer profesionalmente. Mención especial también para mis compañeros de TenerifeDev con los que he compartido tan buenos momentos y de los que he aprendido muchísimo ya sea entre bits o entre beers y me refiero a David Rodríguez (El hombre de la nube), José Fortes (El lobo de Wall Street) y Josué Yeray (No se sabe dónde acaba su enorme corazón). A todos ellos los aprecio muchísimo y los seguiré tomando como referentes.
También he de nombrar a General de Software que me estuvo apoyando mientras estuve en sus oficinas y que me permitió crecer profesionalmente hasta llegar a donde estoy ahora, SolidQ que han confiado en mi y me siguen dando la oportunidad de afrontar nuevos retos día a día y a modo de “aventura” y “juego” porque para mi, mi trabajo es mi hobbie (por suerte o por desgracia) y me divierto con lo que hago.
He dejado para el final a las personas más importantes, mi familia, y en especial a las dos reinas de mi vida, mi mujer y me hija que me permiten cada día robarles un poquito de tiempo para hacer lo que más me gusta, jugar con la tecnología y compartir lo que aprendo.
Así pues, todos aquellos que ya los seáis, tenéis un nuevo compi en la comunidad MVP. Seattle, challenge accepted!!
Este no es un artículo de los que tengo acostumbrado escribir, este artículo es una reflexión-desahogo en la que busco opiniones y consejos de aquellos que tengan los conocimientos y/o las ganas de ilustrarme/nos sobre uno de esos fantasmas con los que me he encontrado a lo largo de mi carrera.
Bueno, al lío. Todo comenzó con la necesidad de usar Silverlight, sí, esa tecnología que parece destinada a quedar en desuso, en una aplicación web ASP.NET MVC y consumiendo datos desde un proyecto WebApi. Hasta aquí toda la mezcla puede parecer normal, ejecuto la aplicación ASP.NET MVC, accedo a la vista con el control Silverlight y… ¡todo correcto! El control muestra todos los datos correctamente y la aplicación funciona perfectamente… ¿o no?
Todo desarrollador web sabe que antes de dar por concluido el desarrollo de una aplicación debe probarla en todos los navegadores y… no señores, esta vez no es IE. En este caso es Firefox el que nos da problemas. ¡Vaya por diox! Resulta que en el navegador del zorrillo, no se me muestran datos porque la respuesta a la petición que he hecho con WebClient retorna un error porque estoy esperando un JSON y resulta que me llega un XML. Surge la pregunta de Mourinho… ¿Por qué?
Una vez puesto el mono de trabajo, abro Fiddler y veo que el parámetro de cabecera “Accept” que se envía desde Firefox es este churrasco que intenta primero obtener HTML, después xhtml, en tercer lugar XML y por último que acepte lo que venga.
Veamos qué en Chrome ni siquiera se establece ese parámetro.
Y finalmente IE que establece */*, o lo que es lo mismo, acepta todo.
Primer intento de solución
Mi primera intención fue forzar el parámetro Accept a */* pero tras ver que no tengo el método “Add” para la colección “Headers” indago un poco y encuentro que para Silverlight se establecen una serie de restricciones de los parámetros de la cabecera y que no podemos modificarlos, entre ellos “Accept” tal y como se especifica en la sección “Comentarios” de este artículo de MSDN.
Y digo yo… pero ¿y qué más da el navegador? Pues bien, resulta que la documentación de Silverlight indica que se establece por el navegador que contiene la aplicación de Silverlight, he aquí el artículo de MSDN que lo explica.
Segundo intento de solución
Usar HttpWebRequest pero sólo obtuve los mismos resultados y problemas.
Solución rápida (sólo para mi)
Podemos cambiar la configuración de Firefox para que el parámetro “Accept” admita antes JSON que XML tal y como se indica en este artículo pero… esto sólo me vale para mi, si la aplicación la va a usar más de… una persona (yo mismo) ya no mola.
Entonces… ¿qué hacer?
Solución aplicada
Una vez me cansé de intentar buscar la forma de establecer desde la aplicación cliente el formato en el que quería recibir los datos (JSON), pensé que puedo ir a WebApi y establecer/forzar que me envíe los datos sólo en el formato que quiero.
NOTA: No me gusta nada esta solución porque pierdo la flexibilidad de WebApi. ¿Y si mañana quiero los datos también en XML?
Gracias a la ayuda de un compañero, encontré que podía forzarlo añadiendo una única línea en el método Application_Start del Global.asax del proyecto WebApi
La misma solución parece un poco más elegante haciéndolo como se indica en este post de StackOverflow pero es más de lo mismo.
La mejor aproximación a la solución es la que se comenta en este artículo que he encontrado pero volvemos a reducirlo a lo mismo.
Vuestra recomendación
Como ya dije al inicio del artículo, espero vuestras recomendaciones, indicaciones y/o palos diciendo ¡eres un inútil! ¡eso no se hace así! ¿Quién es el primero?
Enjoy y recuerda que “cada vez que aparece un fantasma en el código, muere un gatito”
Hoy me gustaría hacer un inciso para hablar de un problema recurrente, de esos como los de convertir o tratar fechas… vamos, un problema que a priori es una tontería pero que nos puede llevar unas cuántas horas de trabajo, y no es otro que… pasar de string a decimal o a double
Escenario
Tenemos una fuente de datos, llámese base de datos, xml, json,…que debemos recibir y parsear en nuestra aplicación .net que incluye un campo de tipo decimal o double y necesitamos parsearlo.
Cualquiera de nosotros lo tendría claro… hacer un parseo con cualquiera de los métodos que hay:
decimal.Parse(string)
Convert.ToDecimal(string)
double.Parse(string)
Convert.ToDouble(string)
…
En principio todos esperamos que esto funcione tal y como podéis comprobar ¿o no?
Si ejecutamos este pedazo de código, efectivamente funcionará y en cada una de las líneas mostrará el valor correcto.
Yujuuuuu… Pero hay algo que se nos escapa y no lo estamos viendo venir porque nos empeñamos una y otra vez en pensar que los datos siempre van a venir como en el ejemplo de turno que teníamos.
Problema
Hasta aquí todo ha ido muy bien, somos unos campeones de tomo y lomo y seguimos programando como si no hubiera mañana pero… se nos ha escapado que la fuente de datos no tiene por qué ser nuestra y debemos controlar que todos los datos estén bien recogidos y parseados. ¿Cómo, no estaba hecho ya? Pues no. Hay algo muy importante que se debe tener en cuenta y es la “cultura” del origen de datos con lo que… en el ejemplo anterior, en vez de “0,123456789” puede que hayamos recibido la cadena “0.123456789” y aquí ya se joroba todo
Oh my god!! ¿Y esto por qué pasa?
La explicación es sencilla, como la cultura que tenemos definida en nuestra máquina de desarrollo define que los decimales se separan con una coma “,” y las unidades de millar con un punto “.”, al hacer el parseo, la aplicación entiende que ese punto es un separador de miles y… nos ha jorobado el día porque a veces no es tan fácil de determinar como en esta “exageración” de decimal que he puesto, pero imaginad que tenéis 137,4 por ejemplo. Si te pilla despistado te puede tener un día entero pensando por qué en el listado que le muestras al usuario salen números que no cuadran con la realidad.
Solución
La solución pasa por pensar que no somos las únicas personas existentes sobre el planeta tierra y que los datos no nos van a venir siempre como queremos, así que tenemos que decirle al sistema de qué cultura vienen nuestros datos. Para ello, basta con mirar la documentación que Microsoft nos aporta sobre Convert.ToDecimal(string, IFormatProvider) y de Convert.ToDouble(string, IFormatProvider) donde se nos indica que basta con establecer la cultura de origen de los datos mediante CultureInfo culture = new CultureInfo(IDENTIFICADOR_DE_CULTURA); y pasárselo al método que estemos usando del Convert. Así pues… el código nos podría quedar así:
NOTA: No os olvidéis de añadir la referencia a System.Globalization
NOTA: Tengamos en cuenta que debemos conocer la cultura en la que recibimos los datos.
Solución +
Pero vamos a ir más allá… y, si seguimos con la idea en la mente de que si quien nos da los datos, nos los da con un formato, seguramente querrá verlos con el mismo formato. Esto vamos a hacerlo mediante el método ToString(IFormatProvider) donde podemos pasarle la cultura que tenemos definida.
Y ahora el usuario podrá ver los datos tal y como los envió
Solución ++
Ahora que nos estamos recreando y podemos decir que somos unos auténticos cracks, que tenemos en cuenta la cultura de los datos y blablablabla… vamos a dar algo de mejora visual al usuario y nos vamos a crear nuestro propio formato numérico para devolver por ejemplo… esos decimales en formato Moneda y en formato Numérico (Tabla de formatos). Así pues, creemos nuestro propio NumberFormatInfo.
Como podréis observar, he introducido los siguientes cambios:
Crear NumberFormatInfo
Definir el signo negativo del formato numérico
Definir el número de decimales para el formato numérico
Definir el número de decimales para el formato moneda
Las dos primeras escrituras en consola lo harán con el formato Moneda – “c” usando el NumberFormatInfo que he creado
Las dos últimas escrituras en consola lo harán con el formato Numértico – “n” usando el NumberFormatInfo que he creado
Para todas las salidas muestro su negativo
El resultado final es este:
Conclusión
No podemos olvidarnos de los usuarios ya que, al fin y al cabo, son los que consumen nuestras aplicaciones y los que nos dan de comer, así que tengamos en cuenta desde donde obtenemos los datos y cómo los vamos a mostrar para que los usuarios siempre reciban la información de la mejor forma posible.
Hoy os traigo un pequeño Tip que, a priori puede ser un poco tonto pero que a más de uno le puede salvar de horas de modificar código o de buscar la aguja en el pajar.
Escenario
Tenemos una aplicación ASP.NET MVC que tiene, dentro de las vistas, llamadas “Ajax” a acciones de la propia aplicación MVC, lo que implicará que tengamos puesto “a fuego” el controlador que queremos llamar.
NOTA: Siempre hay otras formas de hacerlo más elegante.
Problema
Qué ocurriría si:
Cambiamos la acción a otro controlador
Cambiamos el nombre del controlador
Usamos la gran herramienta de todo developer “Copy/Paste” y ponemos este método en otras vistas de otros controladores
…
Bueno, para todas las opciones, lo que ocurre es que tendremos que estar atentos de cambiar el controlador en la “url” que estamos usando en la llamada “ajax” y esto a veces se nos puede pasar por alto y tenernos un buen rato buscando la solución al problema de que de repente no nos funcione nuestra llamada.
Solución
Puede haber muchas soluciones, unas más elegantes que otras como por ejemplo he visto el tener un fichero de recursos con las acciones y sus “url” correctas lo que nos permitiría tener centralizadas todas las posibles llamadas que hagamos y tan sólo tendríamos que pasarle desde el controller las acciones que va a llamar la vista. Pero no es eso lo que yo voy a exponer, sino que en este caso quiero explicar cómo hacer referencia al controlador actual desde la propia vista, con lo que nos ahorraríamos los problemas de un cambio en el controlador.
¿Y cómo conseguimos saber el controlador actual? Pues con una sencilla línea de código.
NOTA: A algunos os podrá extrañar ver el código “razor” dentro de un bloque JavaScript… ¿funcionará? La respuesta es que sí, puesto que razor es capaz de identificar casi siempre el código de que le corresponde después de una @, lo que nos permite hacer cosas tan “fascinantes” y productivas como esta. Algo similar se expone en este artículo. Pero tened cuidado con no abusar de incluir código razor dentro del código JavaScript que al final puede ser peor el remedio que la enfermedad.
Update
Como bien apunta Javier Torrecilla, por buenas prácticas debería utilizar Url.Action para referir la url, con lo que para ser estrictamente correctos, deberíamos hacerlo de la siguiente forma.
Un nuevo apunte de la mano de maese Eduard Tomàs que nos indica “intentar evitar la referencia binaria a HttpContext.Current siempre que se pueda y acceder a los route values a través de PageContext” con @PageContext.Page.Request.RequestContext.RouteData.Values["controller"].ToString() quedándonos de la siguiente forma nuestro código.
En este artículo os voy a mostrar un tip muy sencillo.
Escenario
Se puede dar el caso en el que algún día debáis poner una acción en algún sitio web que tenga como requisito poder imprimir el contenido sin necesidad de generar un documento formateado por ejemplo en PDF.
Solución
Para proveer esta característica, lo mejor es recurrir a JavaScript dado que es una acción de cliente y dado que los datos están ya en el navegador, no necesitamos de enviar nada al servidor. Para realizar esta acción, el código que debemos escribir no podría ser más sencillo. Voy a ilustrarlo con un ejemplo haciendo uso de un «link» que ejecute código JavaScript «unobstrusive».
Como podéis ver, hago uso de jQuery para asignar una función anónima como evento «click» y dentro de esa función hago una llamada al método window.print() de JavaScript. Con esto, cuando un usuario seleccione el enlace, se lanzará la acción de imprimir del navegador que se esté usando.
Ya están disponibles los materiales del Webcast de SUGES que ayer tuve el placer de compartir junto a Adrían Díaz recién nombrado MVP de SharePoint Server. En esta ocasión os hablamos de SharePoint y las aplicaciones para móviles, lo modelos de desarrollo de que disponemos, comparamos aplicaciones nativas, HTML e híbridas, etc. Creo que dejamos un debate muy interesante sobre qué se puede esperar de una aplicación móvil conectada a SharePoint realizando además algunos ejemplos sencillos de cómo podemos realizarlo.
Hoy 23 de enero a las 18:00 hora (GMT+1) tendré el placer de estar junto a Adrían Díaz en un nuevo webcast de SUGES para hablar sobre SharePoint y los dispositivos móviles explicando. Para tal fin, mostraremos cómo podemos consumir los datos de la forma más sencilla desde dispositivos Windows 8, Windows Phone, iOS y Android y de qué herramientas disponemos para ello.