Chalalo Land

Tecnologías ASP.NET y un poco Más

Contacto


 Si quierer cooperar, yo feliz, muy agradecido :)

De donde me Visitan?

Locations of visitors to this page

Generic Content

Si te gustaron los articulos, y te animas te estaría muy agradecido!


Recent Posts

Tags

Community

Blogs de MVP

Amigos Geeks

Blogs Imperdibles

GODS

Archives

Email Notifications

ListView de JqueryMobile Metro Theme con WebMatrix

Una de las demos que hice en el webcast de “Desarrollando Aplicaciones Web para Windows Phone 7 con ASP.NET WebMatrix” en donde vimos temas de jQueryMobile Metro Theme, fue crear una lista de Productos con el Look&Feel de WP7, desarrollada sobre HTML5.

Si quieres ver el material, Slides y Video del webcast, puedes visitar el siguiente Link:

http://geeks.ms/blogs/gperez/archive/2012/05/16/material-charla-desarrollo-de-web-apps-para-wp7-con-webmatrix.aspx

PD: el video no está editado, así que hay lapsus mentales, jejeje, hay alguna que otro bug, pero se entiende.

Antes de seguir, te recomiendo que revises el siguiente link, donde puedes descargar jQueryMobile Metro Theme: http://sgrebnov.github.com/jqmobile-metro-theme/ en donde vas a poder descargar las librerías necesarias para poder utilizarlo y ver ejemplos muy buenos sobre su uso.

También puedes ver un Demo Live en el sitio de GitHub :
https://github.com/sgrebnov/jqmobile-metro-theme

Algunos Screenshot (cool!)

image

Ahora veamos primero los datos a mostrar, para eso examinemos la estructura de la tabla:

image

y a continuación los datos que vamos a mostrar por en el dispositivo:

image

Página Layout2.cshtml

Esta página CSHTML ocupa el concepto de Layout, muy similar a la de las master pages de ASP.NET webforms, esta vez, preparada para un dispositivo móvil(recuerda los tips del screencast, el agregar name= Viewport para tener un tamaño adecuado de la página en un dispositivo de esta naturaleza), en donde tenemos una página principal que tiene las referencias a las librerías de jQueryMobile Metro Theme y las referencias para hacer el render de Title,  MainTitle y RenderBody ( en el cual se dibuja  el contenido)

<!DOCTYPE html>

<html>

<head>

  <meta content="text/html; charset=utf-8"/>

  <meta name="viewport" content="width=device-width, initial-scale=1"/>

  <title>Demo Chalalo</title>

  <link rel="stylesheet"    

          href="DemoJQM/css/metro/jquery.mobile.metro.theme.css"/>

  <script src="DemoJQM/js/jquery.js" type="text/javascript"></script>

  <script src="DemoJQM/js/jquery.mobile.js" type="text/javascript"></script>

  <script src="DemoJQM/css/metro/jquery.mobile.metro.theme.init.js"
          type
="text/javascript"></script
>

  <script src="DemoJQM/js/jquery.globalstylesheet.js"
          type
="text/javascript"></script
>

  <script src="DemoJQM/js/jquery.mobile.themeswitcher.js"
          type
="text/javascript"></script
>

</head>

<body>

   <div data-role="page" class="type-interior" data-theme="a">

      <div data-role="header" data-theme="a">

        <span class="ui-app-title">@Page.Title</span>

            <h1>@Page.MainTitle</h1>          

        </div><!-- /header –>
       @RenderBody()
</body>

</div><!--/page-->

</html>

Página DemoBD1.cshtml

En esta página, primero que nada configuramos el layout a utilizar(Layout2) , luego el title y maintile, para luego hacer la consulta sobre la base de datos. A continuación veremos que los divs tienen el atributo data-role, que corresponde al atributo que identifica JQM para aplicar los estilos correspondientes. Uno de estos estilos es el que asigna para el listview, dejándolo con un Look And Feel muy cool, similar al nativo de WP7.

Luego verificamos la letra con la que comienza el el producto, para ir agregando el separador correspondiente, puedes ver esto en el if del siguiente código, solo cuando hay cambio de letra , agregamos un separador, lo que va a dar un efecto muy cool y similar a la experiencia con una lista de WP7.

@{

   Layout="/_Layout2.cshtml";

   Page.Title ="DEMO";

   Page.MainTitle="Productos";

   var db = Database.Open("Demo");

   var sql = "SELECT Id,Nombre, Precio FROM Productos order by Nombre";

   var data = db.Query(sql);

   var letra="";

}

<div data-role="content" data-theme="a">

<div data-role="fieldcontain">

   <label for="list-view-1">Listado</label><br/>

   <ul id="list-view-1" name="list-view-1" data-role="listview" data-inset="true">
    @{
 
   foreach(var row in data){

      var  PrimeraLetra= Convert.ToString(@row.Nombre[0]);

      if (letra!=PrimeraLetra){

        letra=PrimeraLetra;

        <text><li class="ui-index"
              
data-role="list-divider">@letra</li>
</text>

      }         

    <li><a href="index.html"><img src="demoJQM/images/empty.png" class="ui-li-icon" />@row.Nombre  - @row.Precio</a></li>

                          }

                        }

 

                </ul>

            </div>

</div><!-- /page -->

Y Listo! ya tenemos nuestra lista con un look & feel demasiado cool!!

imageimage

Como ven el efecto es interesante, si quieres descargar el código puedes hacerlo acá:

Descarga

https://www.dropbox.com/s/v9yy4zoqmkm8u03/DemoWP7Web.zip

Espero que te haya servido, nos vemos en un próximo Post Sonrisa
@chalalo

Material Charla :Desarrollo de Web Apps para WP7 con WebMatrix

Hola!, acá les quiero dejar el material, de la charla de Desarrollo de Aplicaciones para WP7: 

View more presentations from Gonzalo C..

Les comparto también el código usado en la presentación de la presentación.
https://www.dropbox.com/s/v9yy4zoqmkm8u03/DemoWP7Web.zip

Y la grabación del video!
PD: No está editado, disculpen las lagunas mentales, jejeje (ese día no tomé desayuno)

Recomiendo verlo en HD (O directamente de Youtube)

Espero que te sirva (el video mientras escribo este post, aun se está procesando en youtube, por lo que es posible que tengas que esperar)

Saludos!
@chalalo

Y vamos por la Flisol 2012, Concepción- Chile

image

Yes!, el sábado 19 a las 10:00 AM estaré hablando sobre MongoDB y ASP.NET Web API + Jquery, con muchos ejemplos y demos. Recordemos de que ASP.NET Web API es un producto OpenSource al igual MongoDB .

Así que si quieres revisar una de las últimos productos del Team de ASP.NET trabajando junto a una base de datos noSQL y con nuestro archi conocido jQuery, nos vemos allá!

Acá está la URL para mayor información: http://concepcion.flisol.cl/ . Se realizará en la Universidad Andres Bello, Sede Concepción

Saludos!
PD: Voy a subir todo el material al blog.

@chalalo

[WP7 Tips] Parar la música al partir si tu app reproduce media

Bueno, no sabía como llamarle al post, pero es simplemente eso, subí una aplicación al market y fue rechazada, el problema? es que se me debía dar la opción de parar la reproducción de media en el caso que se esté reproduciendo algo, mi app utiliza la reproducción de sonido mediante Microsoft.Xna.Framework.Media, entonces,  en pocas palabras, es requisito que manejemos la reproducción de audio en nuestras apps que también lo ocupan.

Entonces, lo que se puede hacer es consultar si es que se está reproduciendo media y si es así parar la reproducción de media, esto lo voy a hacer en el siguiente código:

public main()

{

   InitializeComponent();

    if (Microsoft.Xna.Framework.Media.MediaPlayer.State ==  Microsoft.Xna.Framework.Media.MediaState.Playing)

  {

     if (MessageBox.Show("Actualmente se esta reprouciendo Media, Desea pausar la reproducción? Haga Click en  \"Aceptar\" para pausar la reproducción en curso, \"Cancelar\" para seguir reproduciendo la música y continuar en Dead Dedo", "Reproducción de Media", MessageBoxButton.OKCancel) == MessageBoxResult.OK)

  {

   try

     {

        FrameworkDispatcher.Update();

        Microsoft.Xna.Framework.Media. MediaPlayer.Pause();

     }catch (Exception ex)

     {

        MessageBox.Show(ex.Message);

     }

   }

    else

      {

        App.Current.EnabledSound = false; 

      }

   }

}

Como vez inicialmente se consulta por que estado del mediaplayer, si esta reproduciendo, consultamos al usuario si es que desea pausar la música y seguir con la aplicación, en otro caso, se continuará con la reproducción de media y voy a parar el sonido de mi aplicación con el App.Current.EnabledSound=false, la cual no es nada más que una propiedad en el App.xaml.cs. Para acceder de manera más sencilla ocupo el siguiente código:

public static new App Current

{

    get { return Application.Current as App; }

}

 

public Boolean EnabledSound { get; set; }

Ahora antes de ejecutar un sonido , siempre consulto sobre el estado de la variable. Sin embargo en en algunos casos tenía atachado mediante código XAML el sonido a cierto comportamiento , como por ejemplo los botones:

 

<i:EventTrigger x:Name="trigger1"  EventName="Click"> 
    <eim:PlaySoundAction Volume="1" x:Name="lazer1" Souce="/sound/laser.mp3" />
</i:EventTrigger>

 

Le agregué al EventTrigger un nombre (x:Name) para que sea accesible fácilmente desde el código y poder deatacharlo:

 

if (!App.Current.EnabledSound)

{

     trigger1.Detach();

}

Bueno, luego de arreglar mi problema de esta manera, la aplicación fue aprobada Sonrisa

Espero que este tip te sea útil.

Saludos!

Posted: 7/5/2012 0:07 por Gonzalo Perez | con no comments
Archivado en:
[WebCast] Cómo desarrollar aplicaciones Web en Windows Phone 7 con WebMatrix

Hola, te quiero invitar al siguiente WebCast que voy a dictar Sonrisa

image

Windows Phone 7 ha llegado con un nuevo navegador Web de gran alcance para ayudarle a competir en el mercado de teléfonos inteligentes. Para los desarrolladores que les gusta codificar a mano su HTML, CSS, JavaScript y ASP.NET para crear páginas Web para móviles livianos, WebMatrix es la respuesta. En esta sesión usted aprenderá cómo utilizar WebMatix, la nueva sintaxis de Razor, IIS Express y SQL Server Compact 4.0 para crear aplicaciones Web móviles.

Al mismo tiempo, usted aprenderá importantes prácticas en Web Móvil de W3C, y cómo implementar estándares como XHTML Basic, ECMAScript Mobile Profile y CSS Mobile Profile, con lo que podrá apuntar a cualquier navegador de su teléfono inteligente con su contenido de la Web.

Veremos además como crear Servicios Web con WebMatrix y como consumirlos desde WP7.

Fecha:15/05/2012 Hora 14:00PM Bogotá – 15:00PM Chile

Inscríbete en:
https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032513010&Culture=es-AR

Saludos!
@chalalo

Posted: 5/5/2012 5:27 por Gonzalo Perez | con no comments
Archivado en: ,,
ASP.NET WebForm–Creando un User Control para video HTML5

Hola, hace poco tuve la oportunidad de dar una charla en las oficinas de Microsoft Chile, junto a Pablo Berton, en donde estuvimos hablando de HTML5 sobre nuestros sitios web sin perder la compatibilidad, obviamente Modernizr salió en el juego. Entre las demos, me pareció muy interesante  la de crear Controles de usuario con retro compatibilidad, el ejemplo que vamos a revisar tiene que ver con crear un control para mostrar video, y dependiendo de las capacidades del navegador , vamos a presentar el formato correspondiente, esto último, no lo haremos con Modernizr, si no con la propia detección que provee el tag video.
Vamos a crear entonces, un proyecto de WebForm en la cual voy a agregar un nuevo user control al que llamaremos VideoUserControl.
En el código del control vamos a agregar las propiedades públicas para que podamos modificar  desde el código declarativo estas propiedades del html.


Public Class VideoUserControl

    Inherits System.Web.UI.UserControl

    <BrowsableAttribute(True)> Public Property Width As Integer

    <BrowsableAttribute(True)> Public Property Height As Integer

    <BrowsableAttribute(True)> Public Property Src As String

End Class

Si vemos el código declarativo, se nos aclara el panorama de lo que queremos hacer:

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="VideoUserControl.ascx.vb" Inherits="WebFormDemoHTML5Video.VideoUserControl" %>

<video autoplay="autoplay"
       height="<%=Height %>"
       preload="auto" 
       width="<%=Width %>
">

    <source src="media/<%=Src %>.mp4" type="video/mp4" />

    <source src="media/<%=Src %>.webm" type="video/webm" />

    <source src="media/<%=Src %>.ogv" type="video/ogg" />

    <object data="media/<%=Src %>.swf" 
       height="<%=Height %>" type
="application/x-shockwave-flash"

       width="<%=Width %>">

          <param name="allowfullscreen" value="false">

          <param name="allowscriptaccess" value="always">

          <param name="flashvars" value="file=media/<%=Src %>.swf">

          <!--[if IE]>

             <param name="movie" value="media/<%=Src %>.swf">

          <![endif]-->

        <img alt="Advertisement" 
            height="<%=Height %>"
            src="media/<%=Src %>.jpg"
            width="<%=Width %>"
/>

    </object>

</video>

Podemos apreciar que las propiedades se ocupan justamente para dar formato y elegir la fuente del video, tenemos mp4,webm, ogv , luego en el caso que ninguno de estos formatos se soporten vamos por flash, y si flash no está instalado o está deshabilitado, agregamos una imagen.

Obviamente tenemos estos formatos en nuestra solución:

image_thumb1

Ahora vamos a utilizar y probar nuestro control.Vemos con con opera, esta reproduciendo el video webm( es difícil verlo en una foto, pero créeme)

image_thumb3

Ahora vamos a probar con IE9 con modo de explorador  internet explorer 7

image

Vemos que esta reproduciendo el Flash, y por último, si desactivamos el plugin de flash en nuestro explorador:

image_thumb7

Veremos lo siguiente:

image_thumb9

No hay mucha diferencia verdad, pero esta vez, es una imagen, entonces el objetivo se logra al mostrar la publicidad en distintos formatos, utilizando video html5 y los correspondientes fallback para ofrecen compatibilidad.

Espero que te sirva!
Saludos!
@chalalo

[Tips] Como cambiar el ícono del cursor en una página web.

Una de las consultas que me han hecho es ver como se puede cambiar el cursor del mouse en una página web, tal cual lo hacen el Cut the Rope , el excelente juego hecho en HTML5 bajo IE9, si , como escuchas IE9 Sonrisa, puedes verlo en http://www.cuttherope.ie/

Vamos a copiar los cursores de la app cuttherope, para eso voy a ocupar el depurador de IE9, que obtenemos presionado f12

image

Busqué los archivos cur y obtuve los  archivos handcursor.cur y cursor.cur

image

<!DOCTYPE html>
<html>
       <head>
          <title>Ejemplo de Cursor</title>
          <style type="text/css">
              body{
                  cursor:url(cursor.cur);
               }

               #cara{

                 cursor:url(handcursor.cur);

               }

       </style>

       </head>

       <body>

           <h1>Trabajo con Cursor </h1>

           <img  id="cara" src="cara1.png" />

       </body>

</html>

Se ve que eo body tiene el cursor (cursor.cur) y la imagen el cursor handcursor. Ahora bien, al momento de ejecutar la página en un servidor web (no localmente como archivo html), vemos el resultado que presento en el siguiente video.

Espero que te sirva!, y de repente , quien sabes, te animas a hacer un juego Sonrisa

Saludos!!
@chalalo

Posted: 18/4/2012 5:46 por Gonzalo Perez | con 1 comment(s)
Archivado en:
[WP7 Tips] Guardar lista de objetos en el IsolatedStorage

Hola que tal, otro tips más para el desarrollo sobre Windows Phone. Les cuento a manera de historia lo que me paso.

Tenía la necesidad de guardar en una lista de objetos los resultados obtenidos en el Pseudo juego del que estaba hablando en los post anteriores, los cuales puedes ver acá:

La pantalla de “Logros” es la siguiente:

image

El tema es el siguiente, para guardar una par key-value, funcionaba impecable, revisemos como se guardar un valor y como podemos recuperarlo posteriormente. Primero para guardar un valor lo podemos hacer de la siguiente manera:

IsolatedStorageSettings.ApplicationSettings["clave"] ="algun valor";

o que es lo mismo:

IsolatedStorageSettings.ApplicationSettings.Add("clave", "algun valor");

Lo que se guardar, como decíamos es un par key-value, en donde el value puede ser un objeto.

Para recuperar el dato almacenado, primero debemos preguntar si existe la clave en la colección ApplicationSettings, lo podemos hacer de la siguiente manera:

if (IsolatedStorageSettings.ApplicationSettings.Contains("clave"))

{

  var valor =IsolatedStorageSettings.ApplicationSettings["clave"];

}

Recuerda que el objeto que se retorna no es tipado, por lo que vas a tener que hacer el cast explícito al lo que desees obtener.

Todo funcionaba perfecto, pero cuando quería guardar una lista de objetos, funcionaba en el emulador sin problemas, pero en el dispositivo no se almacenaban los datos, y yo que pensaba que mi aplicación estaba a minutos de poder ser publicada, asi que comencé la búsqueda de mi error.

La lista de objetos almacenaba puntajes, que tiene la siguiente estructura:

image

Que como vez, ocupo la propiedad cara para tener el nombre de la imagen que muestro, el constructor sirve para determinar mediante el puntaje que ruta de imagen se va a almacenar el cara. Además solo quería guardar los 10 últimos puntajes.

public void guardaResultados(int cont)
{

  List<Puntaje> puntajes = new List<Puntaje>();

  Puntaje p = new Puntaje(DateTime.Now.ToString("dd/MM/yyyy hh:mm tt"),
                          Convert
.ToString(cont));

  if (IsolatedStorageSettings.ApplicationSettings.Contains("puntajes"))

  {

      puntajes = (List<Puntaje>)IsolatedStorageSettings.ApplicationSettings["puntajes"];

   }

   puntajes.Insert(0,p);

   if (puntajes.Count > 10)

   {

      puntajes.RemoveAt(10);

    }

   IsolatedStorageSettings.ApplicationSettings.Remove("puntajes");

   IsolatedStorageSettings.ApplicationSettings.Add("puntajes", puntajes);

   IsolatedStorageSettings.ApplicationSettings.Save();

 

}

Como se ve mi función en sencilla, en donde primero creo la lista de Puntaje, instancio el Objeto Puntaje , luego pregunto si ya existía una lista en el ApplicationSettings, si no existe es que se estaba jugando por primera vez, si no la recuperarnos para ingresarle el nuevo objeto p, insertamos en la primera posición, y si hay más de 10, la removemos.

Luego remuevo lo que estaba ya en la colección ApplicationSettings ,esto lo hice por que me levanto una excepción al querer guardar algo que ya tenia la clave, entonces, luego guardo la lista. El método Save no lo estaba ocupando, lei en la documentación que era el método que debía ocupar para guardar la lista, así que lo utilicé pero se levantaba una excepción que indica lo que estaba pasando, debía serializar las propiedades de mi objeto.

Así que rápidamente agregué en la clase Puntaje el namespace:

using System.Runtime.Serialization;

Luego agregué el atributo a la clase Puntaje:

[DataContract]

    public class Puntaje …

y a las propiedades el respectivo DataMember

[DataMember]

   public string cara { set; get; }

Ejecuté ahora mi aplicación en el teléfono y super! ya estaban funcionando la lista de puntajes de manera persistente, ya no se borraban en cada ejecución, justo lo que necesitaba.

Espero que te sirva este tip.

Saludos

@chalalo

Posted: 13/4/2012 15:35 por Gonzalo Perez | con 1 comment(s)
Archivado en:
Estudiantes de Chile, Gran oportunidad para ganar una Xbox desarrollando para Windows Phone 7!!

image

¿Quieres ganar una Xbox 360 con Kinect?
Tienes hasta el 29 de Abril para publicar al menos una aplicación de Windows Phone 7 en nuestro Marketplace.
Recuerda que como Estudiante tienes la posibilidad de registrarte en el Marketplace y utilizar las herramientas absolutamente sin costo.
¡Es muy sencillo programar y publicar aplicaciones! Sólo sigue los siguientes pasos:

image imageimage
image imageimageimage

image

image 
t-laurar@microsoft.com y ya estarás participando!

image

Vamos muchachos, a participar!!!

@chalalo.

[Tips WP7] Abrir ventana del Browser y compartir en redes sociales

Hola, como ya les había comentado , voy a estar compartiendo algunos tips que me sirvieron bastante al momento de comenzar a desarrollar algunas funcionalidades.

Abrir ventana del Browser

Una de las funcionalidades que tiene la app que hice, aunque sea muy poco visible , es que al hacer tap sobre @chalalo, voy a abrir una ventana del explorador a la versión móvil de de la pagina de twitter apuntando a mi cuenta Sonrisa

image

Entonces primero importamos:
using Microsoft.Phone.Tasks;

Para luego asociar al texto TextBlock su handler:

private void tx_chalalo_Tap(object sender, GestureEventArgs e)

{

WebBrowserTask webbrowser = new WebBrowserTask();

webbrowser.Uri = new Uri("http://mobile.twitter.com/chalalo");

webbrowser.Show();

}

Y listo!

Compartir en redes sociales

Una de las funcionalidades que quería era compartir los logros en las redes sociales, primero comencé a revisar el código para ver alguna API de conexión hacia Twitter, después de leer me di cuenta el sdk de WP7 provee todo lo necesario para poder conectarnos a todas las redes sociales que están registradas en el teléfono.

image

Entonces, fue muuuy sencillo, primero  importamos:
using Microsoft.Phone.Tasks;

Para luego asociar al botón el handler

private void Button_Click_2(object sender, RoutedEventArgs e)

{

    ShareStatusTask shareStatusTask = new ShareStatusTask();

    shareStatusTask.Status = "He obtenido " + cont + " puntos! en el Juego Dead Dedo para Windows Phone 7, hell yeah!";

    shareStatusTask.Show();

}

Vemos que la propiedad Status el texto que se va a compartir.,

Luego aparecerá la pantalla para compartir el mensaje

image

Ten en cuenta que no va aparecer en el emulador, pero en el dispositivo físico no hay problema Sonrisa, genial!, muy fácil.

 

Ahh! y que no se me olvide, la primera vez que subí una app al store, fue rechazada por que los screenshot que tomé tenían los datos de debug, (que son los números que están al lado derecho del emulador), lamentablemente estos números aparecen en las imágenes.

image

Para desactivar estos números simplemente vas al archivo App.xaml.cs y comentas la siguiente línea:

//Application.Current.Host.Settings.EnableFrameRateCounter = true;

Y listo! ahora si podemos subir los screenshot sin que los rechacen!
Saludos!

En breve, más tips Sonrisa
@chalalo

Posted: 9/4/2012 21:55 por Gonzalo Perez | con 5 comment(s)
Archivado en:
[WP7] Crónicas de un Aprendiz de WP7 – The Beginning

Hola a todos, que tal? Acabo de subir mi sexta aplicación al Maket Place, ninguna es una gran maravilla, pero fueron parte de mi aprendizaje en el desarrollo de aplicaciones para wp7. Quiero compartir los tips y funcionalidades que anduve buscando en la documentación para poder hacerlo. Me gustaría también en el futuro, y si es que prende la idea en los lectores de este blog, hacer comparaciones entre el desarrollo de Android y WP7. (ya que antes de WP7, desarrollaba y aún desarrollo para Android)

En este proceso de aprendizaje, he creado un pseudo- juego que tiene que ver cuantas veces eres capaz de apretar una calavera en 33 segundos, la app  aún  está  en etapa de evaluación, las funcionalidades son obvias, dentro de los plus son:

  1. Compartir tu puntaje en las redes sociales registradas en el teléfono.
  2. Agregar sonido en Silverlight
  3. Hacer deploy con tipo de letra personalizado
  4. Guardar listas de objetos IsolatedStorageSettings
  5. Abrir IE desde la aplicación

Claro que estas son funcionalidades básicas, pero para los que estamos partiendo creo que serán de gran ayuda Sonrisa

Estos son parte de los screenshot de la aplicación, como dije antes, la hice para aprender y poder enseñar, así que de hoy en adelante, aparte de ASP.NET estaré compartiendo los tips Sonrisa

screenshot0screenshot1screenshot2screenshot3

Esto de hacer apps por jugar ha sido el mejor método que he tenido para aprender a desarrollar para una plataforma.

Nos vemos!!
@chalalo

Posted: 8/4/2012 22:23 por Gonzalo Perez | con 5 comment(s)
Archivado en:
Algunos tips para decidir entre NoSQL y un RDMS

image

Hola, últimamente he estado utilizando MongoDB , estoy muy entusiasmado con este tipo de repositorios, y buscando información acerca de como decidir si usar un RDBMS o un enfoque NoSQL encontré un interesante artículo que es parte de DZone NoSQL Portal. El artículo original está en inglés, voy a intentar traducirlo lo mejor posible.

--- Cualquier persona que no vive en una caverna sabe que NoSQL es una tendencia en aumento para dar soluciones de almacenamiento a gran escala. Sin embargo una pieza que falta en todo esto, es una especie de guía sobre como determinar si la mejor solución es NoSQL o un RDBMS tradicional.

Para comenzar, vamos a decir que debes asumir que un RDBMS es probablemente la apuesta más segura. Casi cualquier cosa se puede hacer con un almacén de este tipo, con la excepción de no poder escalar y/o llevar a cabo tareas con la misma performance que una solución NoSQL. Una de las grandes ventajas de las soluciones RDBMS es que ellos ya cuentan con un enorme ecosistema de herramientas, documentación y dba con experiencia.

Dado lo anterior, ¿por que deberíamos entonces, mirar hacia una solución NoSQL? Los siguientes son algunos indicadores que nos pueden servir para decidir que una solución NoSQL puede ser la mejor opción para solucionar un problema:

  • Estamos almacenando simples pares clave/valor. Si nuestra solución RDBMS termina siendo solo una tabla con un par de campos clave y otro CLOB XML, … entonces probablemente estaremos utilizando la herramienta equivocada para ese trabajo.
  • Estamos almacenando estructuras de datos complejas las cuales son no-relacionales. si almacenamos estructuras con datos jerárquicos en donde cada “Maestro” tiene diferentes “Detalles”, sin un esquema estándar, estaremos en problemas con un RDBMS.
  • Necesitamos escalabilidad masiva y la distribución, y la economía de esa escala es importante para nosotros. Muchas soluciones RDBMS ofrecen partición de esquemas y una muy buena escalabilidad, pero a un costo elevado( licencias y gastos de implantación), que generalmente son mucho más costas que escalar con una solución NoSQL.

Bueno, eso, corta y buena Sonrisa

@chalalo

[Evento] Migrando de HTML 4 a HTML 5 sin quebrar la compatibilidad de tus sitios

Hola!, los quiero invitar a un evento que se va a realizar en las oficinas de Microsoft Chile Sonrisa

Migrando de HTML 4 a HTML 5sin quebrar la compatibilidad de tus sitios

Existe un amplio consenso en que HTML 5 es la plataforma de facto para la nueva Web. Cada día vemos como nuevos browsers, smartphones, tablets y e-readers incorporan soporte para ciertas capacidades del estándar en desmedro de los tradicionales plug-ins. Sin embargo, es también una realidad que una parte importante de nuestros clientes todavía visitan nuestros sitios Web a través de tecnologías más antiguas, sin soporte para muchas de las capacidades que hoy ya son parte del estándar. En esta sesión conoceremos el estado actual del estándar HTML 5 y su soporte en Internet Explorer 9, discutiremos las estrategias disponibles para la transición y mostraremos las herramientas de ASP.NET que nos pueden permitir abordar de mejor manera la evolución hacia HTML 5, manteniendo la compatibilidad con la versión anterior del estándar.
Oradores:
Gonzalo Pérez, Hans Nemarich y Pablo Berton.

Microsoft Chile - Sala Farellones y Colorado
Mariano Sánchez Fontecilla 310 Piso 6
Las Condes Santiago Región Metropolitana Chile

Fecha:
Jueves 26 de Abril desde las 18:30 horas a las 21:30 horas.

Regístrate acá
https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032509406&Culture=es-CL

Nos vemos allá!
@chalalo

Posted: 3/4/2012 23:44 por Gonzalo Perez | con 2 comment(s)
Archivado en: ,
Tutorial Asp.net Web API con MongoDB – Parte 2.3

Hola!, y seguimos con el tutorial de MongoDB + ASP.NET Web API , apoyándonos siempre en jQuery para la funcionalidad del front-end, los post anteriores son:

Esta vez vamos a realizar la funcionalidad de Editar, que encierra la acción de buscar un registro en particular y luego editarlo.

He hecho unos cambios pequeños al ejemplo que hemos estado desarrollando, el primero es que para mostrar el modificar, voy a agregar en la función de mostrar el código para mostrar el botón Modificar, pensé hacer lo mismo que hice con el botón borrar para referenciarlo, pero wait!, no puedo, debido a que en el botón borrar lo tengo asociado como Id, por lo que voy a crear un atributo data-clave al cual voy a asociar el id en el botón modificar:

function muestraFarmacias(farmacias) {

   var li = "";

   $("#lista").empty();

   var href = null;

   $.each(farmacias, function (index, farmacia) {

       li += "<li>" + farmacia.Nombre +

    "<button  class='botonEliminar' id='" + farmacia.Id +"'>Borrar</button>
     <button  class='botonModificar' data-clave='"
+ farmacia.Id +
                                 "'>Modificar</button></li>"
;

   });

    $("#lista").append(li);

    $("#cargando").empty();

}

El cambio que hice sobre sobre el la acción de click sobre el botón Enviar/Modificar la paso a explicar en breve.

Entonces, manos a la obra Sonrisa , el funcionamiento es mega básico: hacer click en el botón modificar de la lista, vamos a obtener los datos y dejarlos en las cajas de texto para poder modificarlos, el botón que antes decía Guardar , debemos setearlo a Modificar, luego de presionarlo, se debe obviamente modificar el registro y volver al estado inicial, el de ingreso de registros.

image

Veamos la acciones del controlador FarmaciaController que nos van a permitir obtener los datos de una farmacia en particular a partir de su Id y el siguiente, que nos va a permitir modificar un registro.

public Farmacia ObtFarmacia(string id)
{ 
try
{   
    FarmaciaModels fm = new FarmaciaModels();
    Farmacia farmacia = fm.GetFarmacia(id);
    if (farmacia != null)
     {
         return farmacia;
     }
    throw new HttpResponseException(HttpStatusCode.NotFound);
}
catch (Exception){
      
throw new HttpResponseException(HttpStatusCode.InternalServerError);

  }

}

 

 

public HttpResponseMessage PutFarmacia(Farmacia farmaciaMod)

  {

     try

        {

           FarmaciaModels fm = new FarmaciaModels();

           fm.PutFarmacia(farmaciaMod);

           return new HttpResponseMessage(HttpStatusCode.OK);

         }

            catch (Exception)

            {

        throw new HttpResponseException(HttpStatusCode.InternalServerError);

            }

}

Como puedes ver la primera acción la utilizo para obtener una farmacia, su nombre comienza con Obt, y es que para no crear otro mapa de rutas, voy a utilizar el que permite agregar el nombre del controlador, acción e Id.

Para la segunda acción voy a utilizar el verbo Http PUT ,que tiene el significado de agregar o reemplazar, en nuestro caso es claramente reemplazar para ejecutar la acción del updatear el registro.

Revisemos ahora los métodos del modelo, que nos van a permitir realizar las tareas que las acciones exponen:

public Farmacia GetFarmacia(string id)

{

    MongoDatabase db = Db();

    return db.GetCollection<Farmacia>("farmacias").FindOneById(id)
}

 

public void PutFarmacia(Farmacia farmaciaMod)

{

  MongoDatabase db = Db();

  var farmacias = db.GetCollection<Farmacia>("farmacias");

  Farmacia farmacia = farmacias.FindOneById(farmaciaMod.Id);

  farmacia.Nombre = farmaciaMod.Nombre;

  farmacia.Direccion = farmacia.Direccion;

  farmacia.Telefono = farmacia.Telefono;

  farmacia.Comuna = farmacia.Comuna;

  farmacia.Latitud = farmacia.Latitud;

  farmacia.Longitud = farmacia.Longitud;

  farmacias.Save<Farmacia>(farmacia);

}

Destaca la simplicidad de los métodos, el primero para obtener una farmacia en particular, en donde instanciamos una colección de farmacias y sobre ella ejecutamos el método FindOneByID que permite buscar un elemento en la colección de MongoDB mediante el Id especificado para el objeto farmacias. Esto se hace con “carga demorada”  y es una consulta compilada, es decir, no se obtiene toda la colección y sobre ella luego se filtra, si no que se hace la consulta directamente y muy optimizada de parte del motor para obtener un único registro.

Ahora para Modificar una farmacia, lo que hago es pasar el objeto que se va a modificar, el cual viene con el Id original y los datos modificados desde el formulario, para el Id cree una variable oculta (hidden field) dentro del formulario para guardar el valor. Luego obtengo el objeto y sobre escribo sus propiedades y luego lo guardo con el método Save.

Ahora que ya vimos el BackEnd, vamos a ver los métodos en el frontEnd que nos van a permitir llamar a las acciones:

Funciones Javascript, utilizando jQuery por su puesto, la primera para asociar el evento Click sobre el botón modificar, el cual llama a la acción del controlador ObtFarmacia,una vez que se obtienen los datos, se llama la funcion muestraFarmacia, que sirve para mostrar los datos en el formulario y setear el Id en el campo oculto, para tener disponible el Id para ejecutar el update.

    $(".botonModificar").live("click", function () {

            var id = $(this).attr("data-clave");
              $.ajax({
                 url: "http://localhost:51753/Api/Farmacia/ObtFarmacia/"+id,

                 type:"GET",

                contentType: "application/json;charset=utf-8",

                statusCode: {

                    200: function (farmacia) {

                        muestraFarmacia(farmacia);

                    },

                    400: function () {

                        $("#mensaje").text("Error en la Petición");

                    },

                    404: function () {

                        $("#mensaje").text("Datos no Encontrados");

                    },

                    500: function () {

                        $("#mensaje").text("Error en el servidor");

                    } 

                }

            });

        });

 

        function muestraFarmacia(farmacia) {

            $("#Id").val(farmacia.Id);

            $("#Nombre").val(farmacia.Nombre);

            $("#Direccion").val(farmacia.Direccion);

            $("#Telefono").val(farmacia.Telefono);

            $("#Comuna").val(farmacia.Comuna);

            $("#Latitud").val(farmacia.Latitud);

            $("#Longitud").val(farmacia.Longitud);

            $("#Fecha").val(farmacia.Fecha);

            $("#boton").val("Modificar");

        }

Ahora veamos la modificación que se hizo sobre el manejador del Submit del formulario, acá es donde se hizo la modificación, primero definimos una variable verbo, que según el botón esta en estado modificar, será PUT o de caso contrario, será POST, esto es para determinar a que acción del controlador vamos a llamar , PostFarmacia para ingresar o PutFarmacia para actualizar, recuerda que el tema de ingreso y borrado están en los post anteriores.

También seteo una variable acción de manera de poder enviar un msg adecuado al contexto la cual puede ser “Insertar” y “Modificar”.

Una vez que ya ejecutamos la llamada ajax mediante jQuery, limpiamos los elementos input, con lo que la variable oculta que contiene el Id también se limpia, también al botón lo volvemos a su texto original “Guardar”

 

$('#formulario').submit(function (event) {

        var verbo = "POST"

        var accion = "Insertar";

        if ($("#boton").val() == "Modificar") {

            verbo = "PUT";

            accion = "Modificar";

        }

            event.preventDefault();

            $.ajax({

                url: "http://localhost:51753/Api/Farmacia",

                type: verbo,

                contentType: "application/json;charset=utf-8",

                cache: false,

                data: JSON.stringify($(this).serializeObject()),

                statusCode: {

                    200: function (farmacia) {

                        listaFarmacias();

                     

                    },

                    500: function () {

                        alert("Error al " + accion);

                    }

                }

            });

            limpiar();

        });

 

    function limpiar() {

        $(":input").val("");

        $("#boton").val("Guardar");

    }

 

Finalmente el funcionamiento queda de la siguiente manera, recuerda que no hemos hecho nada por el diseño, es solo funcionalidad, y si, de nuevo no arreglé lo de Regitros Triste

Espero que te sirva!, luego seguimos con el tema de seguridad Sonrisa
Saludos

@chalalo

Elegido nuevamente MVP ASP.NET/IIS -2012

En Hora Buena! Sonrisa, he sido elegido nuevamente MVP ASP.NET/IIS, ya son 7 años , y cada año siempre vuelve el nerviosismo de si es que calificaste o no.

El año pasado fue particularmente difícil, pero gracias a Dios, pude concretar proyectos de Webcast, ScreenCast, charlas y artículos. He tratado de responder todos los correos, pido las disculpas por si he olvidado alguno. Siempre digo que el MVP es la consecuencia de lo que me apasiona, no es el el solo hecho de ser MVP.  Debido a que hay un amplia tendencia al mundo del desarrollo móvil, en el cual he estado trabajando bastante, tuve menos tiempo para dedicarle a mi pasión, el desarrollo Web, pero bueno, creo finalmente todo salió bien.De hecho, además de ASP.NET próximamente estaré posteando tips para Windows Phone 7.

También estoy muy contento sobre la noticia de que ASP.NET MVC 4 con Razor y ASP.NET Web API son OpenSource, no lo sabías? mira este artículo, me gusta mucho el OpenSource (aunque algunos crean que no), esto abre muchas nuevas posibilidades de cooperación y mejora de estos  excelentes productos.

Y Bueno, por ultimo agradecer a todos las personas que leen este humilde blog, trato de aportar con lo que pueda servir, muchas gracias!!!

image

@chalalo.

[Invitación] WebCast MSDN–CSS3 se toma el mundo!
Como tesoro de guerra de los desarrolladores Web están Photoshop, HTML, JavaScript y, por supuesto, CSS. Mientras CSS comenzó con un papel de menor importancia, cada vez más está tomando el control. Esta sesión examinará el CSS3 más reciente e importante, ¿cómo se puede aplicar a los proyectos en este momento?, ¿qué beneficios puede tener? y ¡lo que podemos esperar tener a nuestra disposición en el futuro al seguir CSS tomando al mundo!

Regístrate en:
https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032509178&Culture=es-AR

Fecha : 18/04/2012 a las 16:00 horas Chile , 14:00 horas Bogotá

Nos vemos allá!
Saludos!

@chalalo

Tutorial Asp.net Web API con MongoDB – Parte 2.2

Estamos ya en la segunda parte de la segunda parte (2.2), Lengua fuera del tutorial en donde estamos viendo MongoDB + ASP.NET Web API + jQuery. En este post vamos a ver el listar datos y el eliminar.

Url del post anterior:
http://geeks.ms/blogs/gperez/archive/2012/03/19/tutorial-asp-net-web-api-con-mongodb-parte-2-1.aspx

Importante

He hecho cambios desde el post anterior, que nos van ayudar a acceder desde jQuery, el primero tiene que ver con la generación del ObjectID de la clase Farmacia, ahora es un StringObjectIdGenerator, el cual permite generar una clave única de tipo String, debido a que el retorno hacia jQuery, con la solución anterior, tenía la siguiente estructura:

"timestamp":1298346771,
"machine":8775338,
"pid":20092,
"increment":0

Que corresponde, como antes mencionaba, al objeto ObjectID, por lo que leyendo la documentación encontré que era más acertado para trabajar con jQuery el StringObjectIdGenerator que permite generar una clave pero que tenga el formato de un String, por lo que mi clase Farmacia queda finalmente de la siguiente forma:

public class Farmacia
{

[BsonId(IdGenerator = typeof(StringObjectIdGenerator))]

public String Id { get; set; }

[BsonRequired]

public string Nombre { get; set; }

[BsonRequired]

public string Direccion { get; set; }

[BsonIgnoreIfNull]

public string Telefono {get;set;}

[BsonRequired]

public string Comuna { get; set; }

public string Latitud { get; set; }

public string Longitud { get; set; }

[BsonRequired]

public string Fecha { get; set; }

}

También hice un cambio en el tipo de retorno del método PostFarmacia del ejemplo anterior, ahora retorna un HttpResponseMessage, que es el adecuado para enviar responses con código de estado.

     

Ahora bien al formulario anterior solo vamos agregar una lista con cero diseño, con el nombre de la farmacia y al lado un botón eliminar. A continuación te dejo el video con el funcionamiento final.

(PD: sí, el título dice Regitros en vez de Registros, pero bueno se entiende no?)

Como está de moda el estilo metro, agregué en la funcionalidad un gif animado con el loading metro’s style, para darle un look (si es que este demo tiene algún look) un poco mejor. T dejo el gif para que lo utilices en tus desarrollos (así que dale al botón derecho y guardar!)

animated_loader

Veamos ahora el controlador y modelo para las dos acciones, Listar y Borrar.

Nuevas acciones del Controlador FarmaciaController

public IEnumerable<Farmacia> ListFarmacias()

{

   try

     {

       System.Threading.Thread.Sleep(4000);

       FarmaciaModels fm = new FarmaciaModels();

       var lista = fm.ListFarmacias();

       if (lista != null)

       {

          return lista;

        }

        throw new HttpResponseException(HttpStatusCode.NotFound);

      }
     
catch (Exception){

        throw new HttpResponseException(HttpStatusCode.InternalServerError);

      }

  }

 

    

public HttpResponseMessage DeleteFarmacia(string id)

{

    try

      {

        FarmaciaModels fm = new FarmaciaModels();

        fm.DeleteFarmacia(id);

        return new HttpResponseMessage(HttpStatusCode.NoContent);

      }

      catch (Exception)

     {

       throw new HttpResponseException(HttpStatusCode.InternalServerError);

     }

  }

     

Puedes observar en la primera acción que hago una pausa de 4 segundos (para que se vea el loading, que esta muy cool Sonrisa), luego voy a consultar al modelo sobre los datos, luego según si obtengo o no resultados y si hay o no erro, devuelvo código HTTP según la situación. La acción DeleteFarmacia  (ojo, se debe empezar por Delete, para que podamos accederla correctamente), recibe el id como un string (que fue uno de los cambios que hice), luego le pasamos la responsabilidad al modelo para que borre el registro desde MongoDB.

Métodos en el Modelo FarmaciaModels

public IEnumerable<Farmacia> ListFarmacias()

{

   MongoDatabase db = Db();

   MongoCollection<Farmacia> farmacias = db.GetCollection<Farmacia>("farmacias");

   return farmacias.FindAll().ToList<Farmacia>();

}

public void DeleteFarmacia(string id)

{

  MongoDatabase db = Db();

  MongoCollection<Farmacia> farmacias =
                                  db.GetCollection<
Farmacia> ("farmacias"
);

  db.GetCollection<Farmacia>("farmacias").FindAndRemove(Query.EQ("_id", id),
                                                  
SortBy.Ascending("id"
));

}

Anteriormente ya había comentado que estábamos simplificando al máximo nuestros métodos. El primero de ellos obtiene la colección de farmacias y simplemente la retorna. El segundo método, obtiene la referencia hacia la colección y utilizamos el método FindAndRemove de la API de Mongodb, para buscar y eliminar el elemento a partir de una consulta sobre MongoDB, que es Query.EQ("_id", id), es decir, buscamos y eliminamos por el Id.

Para poder acceder a la acción ListaFarmacias  del controlador debemos agregar una nueva mapa en la Ruta:

routes.MapHttpRoute(

    name: "AccionesAPI",

    routeTemplate: "api/{controller}/{action}/{id}",

    defaults: new

    {

       id = UrlParameter.Optional

     }

);

Con esto podemos acceder al controlador y la acción, y el parámetro id es opcional.

Ahora el Front End

Nuestro Front End tiene ciertas modificaciones al del ejemplo anterior, los cuales son más que nada , una lista para agregar las farmacias y unas cuantas funciones más de JavaScript, partamos por el código HTML que agregué:

<div id="div_lista">
        <h2>Listado de Registros de Farmacias</h2>
        <div id="cargando"></div>
        <ul id="lista"></ul>
</div>

Funciones Javascript

   function listaFarmacias() {

            $("#cargando").html("<img src='animated_loader.gif' />");

            $.ajax({

                url: "http://localhost:51753/Api/Farmacia/ListFarmacias",

                type: "GET",

                contentType: "application/json;charset=utf-8",

                cache:false,

                statusCode: {

                    200: function (farmacia) {

                        muestraFarmacias(farmacia);

                    },

                    400: function () {

                        $("#mensaje").text("Error en la Petición");

                    },

                    404: function () {

                        $("#mensaje").text("Datos no Encontrados");

                    },

                    500: function () {

                        $("#mensaje").text("Error en el servidor");

                    }

 

                }

 

            });

        }

La función de listaFarmacias la cual llama a la acción ListaFarmacias y en el caso que la respuesta tenga un statusCode 200, es decir, todo ok, hacemos una llamada a la función muestraFarmacias pasándole la data que fue retornada desde el servidor.

function muestraFarmacias(farmacias) {

  var li = "";

  $("#lista").empty();

  var href = null;

  $.each(farmacias, function (index, farmacia) {

    li += "<li>" + farmacia.Nombre + "<button class='botonEliminar' id='" +
          farmacia.Id +
"'>Borrar</button></li>"
;

  });

   $("#lista").append(li);

   $("#cargando").empty();

}

Esta función esta encargada de crear los items de lista, cada ítem tiene un botón asociado cuyo id es el Id proveniente del servidor, es decir el Id del registro obtenido desde MongoDB, esto sirve para asociar el botón al registro en particular, además podrás notar que el botón tiene una clase asociada, de manera que podemos atachar a esa clase el evento click:

$(".botonEliminar").live("click", function () {

            var id = $(this).attr("id");

            $.ajax({

                url: "http://localhost:51753/Api/Farmacia",

                data: JSON.stringify({ id: id }),

                cache: false,

                type: "DELETE",

                contentType: "application/json;charset=utf-8",

                statusCode: {

                    204: function () {

                        listaFarmacias();

                    }

                }

            });

        });

Con este manejo del evento click, hacemos la llamada al eliminar, fíjate que debemos especificar en type Delete para que pueda hacer referencia a la acción DeleteFarmacia del controlador, puedes ver más detalles de la función $.ajax de jQuery en http://api.jquery.com/jQuery.ajax/ , finalmente si recibimos la respuesta 204, volvemos a listar las farmacias.


Eso es todo por ahora, continúo luego con el modificar y el acceso desde dispositivos móviles.

Saludos!
@chalalo

Tutorial Asp.net Web API con MongoDB – Parte 2.1

Hola, vamos a ver la primera parte de la segunda parte (suena raro, o la parte 2.1) del tutorial de MongoDB y ASP.NET Web API, la primera parte esta en:

http://geeks.ms/blogs/gperez/archive/2012/03/11/tutorial-asp-net-web-api-con-mongodb-parte-1.aspx

Debido a que he estado corto de tiempo, preferí escribir de inmediato el insertar datos desde jQuery , pasando por Web API a MongoDB. Bueno acá vamos Sonrisa

Formulario de Ingreso con un poco de HTML5

Voy a utilizar un formulario muy sencillo con validación required de HTML5, como ves , además cambiamos el mensaje de la validación con la propiedad Title, puedes notar que para cambiarlo en Firefox ocupamos x-moz-errormessage (espero que esto no sea así en el futuro, y que exista una propiedad estándar) . Luego el estilo de los labels es display: block para que el orden quede vertical.

image image

Veamos el código del formulario:

 

  <form id="formulario">

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

        <input type="text" id="Nombre" name="Nombre" required

            title="Debe ingresar el Nombre de la farmacia"

            x-moz-errormessage="Debe ingresar el Nombre de la farmacia"/>

 

        <label for="Direccion">Dirección:</label>

        <input type="text" id="Direccion" name="Direccion" required

            title="Debe ingresar la Dirección"

            x-moz-errormessage="Debe ingresar la Dirección" />

 

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

        <input type="tel" id="Telefono" name="Telefono" required

              title="Debe ingresar el telefono"

              x-moz-errormessage="Debe ingresar el telefono" />

 

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

        <input type="tel"  id="Comuna"  name="Comuna" required

              title="Debe ingresar la Comuna"

              x-moz-errormessage="Debe ingresar la Comuna" />

 

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

        <input type="number" id="Latitud" name="Latitud"  required

              title="Debe ingresar la Latitud"

              x-moz-errormessage="Debe ingresar la Latitud" />

 

 

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

        <input type="number"  id="Longitud"  name="Longitud" required

              title="Debe ingresar la Longitud"

              x-moz-errormessage="Debe ingresar la Longitud" />

 

 

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

        <input type="date"  id="Fecha" name="Fecha" required

              title="Debe ingresar la Fecha"

              x-moz-errormessage="Debe ingresar la Fecha" />

 

        <input type="submit" value="Guardar" />

    </form>

Bastante simple, nada del otro mundo, ahora veamos el código jQuery para el envío de datos:

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></script>

<script>

    $(document).ready(function () {

 

        $('#formulario').submit(function (event) {

            event.preventDefault();

          $.ajax({

                url: "http://localhost:51753/Api/Farmacia",

                type: "POST",

                contentType: "application/json;charset=utf-8",

                data: JSON.stringify($(this).serializeObject()),

                statusCode: {

                    200: function (farmacia) {

                        alert("Registro Insertado");

                    },

                    500: function () {

                        alert("Error al Insertar");

                    }

                }

            });

        });

 

        $.fn.serializeObject = function () {

            var o = {};

            var a = this.serializeArray();

            $.each(a, function () {

                if (o[this.name] !== undefined) {

                    if (!o[this.name].push) {

                        o[this.name] = [o[this.name]];

                    }

                    o[this.name].push(this.value || '');

                } else {

                    o[this.name] = this.value || '';

                }

            });

            return o;

        };

    });

</script>

Como vez, lo primero que hacemos es prevenir el evento por default del botón submit, de manera que no exista una recarga de página, luego configuramos la petición Ajax, vamos enviar estos datos por POST y esto repercute, como veremos más adelante, en el nombre del controlador. Los datos los voy a enviar mediante JSON, para esto ocupo una función de serialización y luego utilizamos la función JSON.stringify para dar el formato correcto, puedes ver más sobre esta función acá:http://msdn.microsoft.com/en-us/library/cc836459(v=vs.85).aspx

De hecho cuando lo ejecutemos e inspeccionemos JSON.stringify($(this).serializeObject()) veremos:

image

Ahora revisemos como vamos a recibir estos datos, veamos el controlador, en nuestro caso seguimos en el controlador

Acción en el Controlador FarmaciaController

  public HttpStatusCode PostFarmacia(Farmacia farmaciaInsert)

   {

      try

        {

          FarmaciaModels fm = new FarmaciaModels();

          fm.PostFarmacia(farmaciaInsert);

          return HttpStatusCode.OK;

        }

         catch (Exception)

         {

        throw new HttpResponseException(HttpStatusCode.InternalServerError);

        }

   }

Este controlador esta simplificado para fines del ejemplo, cabe destacar que debido a que nombre de nuestro método comienza con "Post" no necesitamos crear una nueva ruta customizada, el Método PostFarmacia puede ser invocado con  URL /Api/Farmacia, y este método será invocado bajo el contexto de un request HTTP POST.


Podría devolver además alguna variable desde el modelo, pero para nosotros por el momento va a estar ok. Si inspeccionamos el objeto farmaciaInsert veremos que los datos vienen correctamente:

 

image

En caso de resultar todo ok, devolvemos el statusCode en 200, es decir OK Pulgar hacia arriba, y en el caso contrario levantamos una excepción con un error 500 (HttpStatusCode.InternalServerError) . Estos Status Code son los que estamos evaluando con jQuery y de ello dependerá la respuesta que demos al usuario.

Modelo

Al igual que nuestro controlador, el modelo esta simplificado al máximo, de manera de centrarnos en lo importante para el ejemplo. Instanciamos una colección de farmacias, a la cual le insertamos el objeto farmaciaInsert

public void PostFarmacia(Farmacia farmaciaInsert)

{

   MongoCollection<Farmacia> farmacias = Db().GetCollection<Farmacia>
                                       (
"farmacias"
);

   farmacias.Insert(farmaciaInsert);

}

Ahora cuando nuestro proceso esté terminado veremos que se ejecuta la sección asociada al Status Code :200

image

Y si revisamos con el IDE MongoVUE, veremos el dato ingresado:

image

 

Y todo con unas pocas líneas de código Sonrisa
Saludos!
@chalalo

[Utilidad] Metro Studio 1, software que nos permite obtener iconos Metro Style :)

image

Por esas cosas de la vida he encontrado un software que me parece de mucha utilidad, que nos permite obtener iconos de tipo Metro, que nos van a servir para nuestras aplicaciones Metro para Windows 8 o para Windows Phone, se llama MEtro Studio 1 y lo puedes descargar tras un pequeño registro acá:

http://www.syncfusion.com/downloads/metrostudio

Como ves, el clásico siguiente siguiente siguiente……..

image

Luego de la instalación vamos a ver una gran cantidad de iconos agrupados por categoría:

image

Con la posibilidad de modificar cada uno de ellos en tamaño, fondo, y otras características, para luego descargarlo como PNG

image

Bueno, eso un pequeño tip que nunca está demás

@chalalo

Tutorial Asp.net Web API con MongoDB – Parte 1

Hola, en esta primera parte del un tutorial en el cual vamos a estar trabajando con ASP.NET Web API junto a MongoDB, adicionalmente vamos a utilizar también jQuery y Windows Phone 7 como cliente.

El contexto de la aplicación es el siguiente, existen farmacias de turno, que se pueden consultar mediante la ciudad y la fecha. Entonces la idea es disponibilizar esta información mediante la Web Api, por lo tanto la primera parte de este tutorial tiene que ver con esta consulta.

Entonces el tutorial se dividirá en las siguientes partes:

  • Parte 1 : Creación de Proyecto, Controlador , consulta de datos con jQuery
  • Parte 2: Inserción , Borrado y Modificación
  • Parte 3: Autorización
  • Parte 4: Consumo de datos mediantes WP7
  • Como esta es la parte 1 , vamos a revisar paso a paso lo que necesitamos para comenzar:

    Primero , crear un proyecto ASP.NET MVC 4 Web Application:

    image

    Luego se nos presenta una pantalla con las distintas plantillas con las que podemos trabajar, obviamente vamos a seleccionar Web API

    image

    Luego ya tenemos la estructura del proyecto. Paso siguiente es hacer referencia a las librerías de MongoDB, para mayor información revisa este post que hice sobre ello: http://geeks.ms/blogs/gperez/archive/2011/12/02/tutorial-mongodb-con-asp-net-mvc-ejemplo-pr-225-ctico.aspx

    image

    En mi caso voy a crear mi propio controlador, no voy a utilizar el que viene por defecto, así que agrego un nuevo controlador, seleccionado Add, Controller

     

    image

    Agrego entonces mi “FarmaciaController” utilizando el template Empty API Controller,

    image

    El template seleccionado nos entrega un controlador vacío, al cual agregaremos la acción que necesitamos, consultar por ciudad y fecha.

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    using FarmaciasWebAPI.Models;

    namespace FarmaciasWebAPI.Controllers

    {    public class FarmaciaController : ApiController    {

            public Farmacia GetFarmacia(string comuna, string fecha) {

              FarmaciaModels fm = new FarmaciaModels();
              Farmacia farmacia = fm.GetFarmacia(comuna, fecha);
              if (farmacia != null){
                   return farmacia;
              }
              throw new HttpResponseException(HttpStatusCode.NotFound);
            }

        }
    }

     Es una buena práctica devolver una excepción del tipo HttpStatusCode.NotFound, ya que de esta manera podemos manejas los estados del Http Response en jQuery de manera más cómoda. Como puedes ver, instanciamos el modelo y  ejecutamos su método GetConsulta. Veamos el código del modelo:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using MongoDB.Bson.IO;
    using MongoDB.Bson.Serialization;
    using MongoDB.Bson.Serialization.Attributes;
    using MongoDB.Bson.Serialization.Conventions;
    using MongoDB.Bson.Serialization.IdGenerators;
    using MongoDB.Bson.Serialization.Options;
    using MongoDB.Bson.Serialization.Serializers;
    using MongoDB.Driver.Builders;
    using MongoDB.Driver.GridFS;
    using MongoDB.Driver.Wrappers;
    using MongoDB.Driver;
    using MongoDB.Bson;

     namespace FarmaciasWebAPI.Models
    {
        public class FarmaciaModels    {

         private MongoDatabase Db()  {
           string connectionString = "mongodb://localhost";
           MongoServer server = MongoServer.Create(connectionString);
           MongoDatabase db = server.GetDatabase("farmaciasTurno");
           return db;
       }

       public Farmacia GetFarmacia(String comuna, string fecha)
      {

        MongoDatabase db = Db();
       
    MongoCollection<Farmacia> farmacias =
                                      db.GetCollection<
    Farmacia>("farmacias"
    );

        var query = Query.And(
                      Query.EQ("Comuna",comuna),
                      Query.EQ("Fecha",fecha)
                  );

        Farmacia farmacia = farmacias.FindOne(query);
        return farmacia;
       }

      }
    }

    Puedes ver que tenemos la conexión, obviamente en ambientes del producción vamos a necesitar el string de conexión con autenticación.
    Veamos el método GetFarmacias que recibe los parámetro comuna y fecha para luego ejecutar la consulta sobre la colección que se obtiene desde mongo.
    El clase farmacia tiene la siguiente estructura:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using MongoDB.Bson.Serialization.Attributes;
    using MongoDB.Bson.Serialization.IdGenerators;
    using MongoDB.Bson; 

    namespace FarmaciasWebAPI.Models{

        public class Farmacia
        {  [BsonId(IdGenerator = typeof(CombGuidGenerator))]
            public Guid Id { get; set; }

           [BsonRequired]
            public string Nombre { get; set; }

           [BsonRequired]
            public string Direccion { get; set; }

           [BsonIgnoreIfNull]
            public string Telefono {get;set;}

           [BsonRequired]
            public string Comuna { get; set; }

            public string Latitud { get; set; }
            public string Longitud { get; set; }

            [BsonRequired]
            public string Fecha { get; set; }

        }

    }

    Pero se me queda algo en el tintero, debemos modificar el global.asax  para agregar un MapRoute nuevo, de manera que nos permita llamar a un controlador con la acción que ya vimos, es decir con dos parámetros.

       routes.MapHttpRoute(
                    name: "ConsultaDefaulWebApi",
                    routeTemplate: "api/{controller}/{comuna}/{fecha}",
                    defaults: new { }
       );

       (En este caso los parámetros no son opcionales)

    Ahora podemos ejecutar nuestro proyecto,a modo de ejemplo ingreso la siguiente URL:

    http://localhost:<puerto>/Api/Farmacia/Concepcion/27-04-2012

    Y vemos:

    image

    Ahora que estamos ok con nuestro BackEnd, vamos a programar el front-end, de manera muy sencilla, la idea es que al presionar un botón buscar, veamos la información de la farmacia solicitada y que podamos ocupar la información de Latitud y Longitud para geo referenciarla:

    image

    El código JavaScript es el siguiente:

    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></script>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true" ></script>

    <script>
        $(document).ready(function () {
            $("#buscar").on({
                click: function () {
                    var data = "/Concepcion/27-04-2012";
                    $.ajax({
                        url: "http://localhost:51753/Api/Farmacia" + data,
                        type: "GET",
                        contentType: "application/json;charset=utf-8",
                        statusCode: {
                            200: function (farmacia) {
                                muestraMapa(farmacia);
                            },
                            400: function () {
                                $("#mensaje").text("Error en la Petición");
                            },
                            404: function () {
                                $("#mensaje").text("Datos no Encontrados");
                            },
                            500:function(){
                                $("#mensaje").text("Error en el servidor");
                            }
                        }

                    });
                }
            });

    function muestraMapa(farmacia)
    {
      $("#mensaje").text(farmacia.Nombre + " " +
                          farmacia.Direccion + " " +
                          farmacia.Comuna + 
                          " Fono:" + farmacia.Telefono);

       var lat = farmacia.Latitud;
       var lon = farmacia.Longitud;
       var options = { zoom: 13,
            center: new google.maps.LatLng(lat, lon), 
            mapTypeId: google.maps.MapTypeId.ROADMAP
            }

       var map = new google.maps.Map($("#canvas").get(0), options);
                var marker = new google.maps.Marker({ position: new
                                                google.maps.LatLng(lat, lon) });

                marker.setMap(map); 
     }

     });

    Como puedes apreciar agregamos un manejador para el evento click del botón, el cual utiliza la función $.ajax de jQuery, puedes notar que no ocupo la propiedad data, más bien una variable data que tiene los parámetros como ruta. Luego y dependendiedo del  código del HTTP Response podemos decidir que hacer. El código 200 corresponde a OK, por lo que vamos a la función muestraMapa, que hace uso de la API de Google para geolocalización para mostrar el mapa y el marker en la posición solicitada.
    Como vez, bastante sencillo, espero que este ejemplo te sirva.
    Saludos!
    @chalalo

    Posted: 11/3/2012 20:24 por Gonzalo Perez | con 3 comment(s) |
    Archivado en: ,
    Más artículos Página siguiente >