Aplicaciones imprescindibles en Windows Phone 7

Después de probar varias aplicaciones disponibles actualmente en el marketplace de Windows Phone 7, me gustaría compartir aquellas que creo que son imprescindibles en nuestros dispositivos :)  

Adobe Reader: Una de las aplicaciones que no necesita presentación. Gracias a ella podremos disfrutar de nuestros archivos en formato PDF.
Facebook: Aplicación oficial desarrollada por Microsoft Corporation. En una versión anterior presentaba bastantes errores de refresco y en ocasiones se quedaba colgada. Recientemente ha mejorado de forma considerable. Si bien una de las cosas que admiro de Windows Phone 7 es su gran integración con Facebook (permite escribir en muros, imágenes, perfil etcétera desde el propio sistema operativo), si queremos una aplicación exclusiva para esta red social, la versión oficial es altamente recomendable.
Foursquare: Aplicación oficial de foursquare. Para todos aquellos amantes del check in :D
4th & Mayor: Otro cliente para Foursquare, del cual dicen que será el sucesor de la versión oficial. Si bien a día de hoy la versión oficial sólo soporta check-in, con este cliente podremos además la crear y visualizar fotos de los lugares, disfrutar de nuevas features como “explore”, mayor rápidez en la localización de sitios próximos, entre otras.
Flory: Se trata de una aplicación dedicada a la mensajería instantánea. Actualmente nos da soporte para Google Talk y Facebook, aprovechando las notificaciones Push y Tile. Todos los mensajes son securizados y encriptados a 256 bits.
Messenger by Miyowa: Si bien la versión Mango (Windows Phone 7.5)  incorporará Windows Live Messenger, mientras tanto podemos ir abriendo boca con este cliente con notificaciones Tile.
Beez: Cliente para la famosa red social Twitter con notificaciones Tile. Una de las características que más me motivan al utilizar un cliente para esta red social es poder recibir notificaciones de menciones y mensajes privados que recibo a través de la misma. Esta es la aplicación que más se acerca a mis necesidades, aunque las notificaciones llegan en ocasiones con un retardo considerable :(
Twitter: Aplicación oficial para Twitter. Encantada con su interfaz gráfica donde podemos ver claramente toda la información de la plataforma. A diferencia de la anterior no aprovecha las notificaciones Tile… Por el momento espero :)
Birdsong: Otro cliente de Twitter con gran acogida que nos ofrece nuevas características: configuración del timeline con listas, búsquedas guardadas, etcétera, integración de las imágenes twitteadas, tweets mostrados en modo conversación, thread de mensajes privados, integración con Places, etcétera.
Rowi: Cliente de pago para Twitter que nos ofrece notificaciones push y una interfaz limpia. Si bien dispone de una versión free con el inconveniente publicitario :) por $2,99 podemos disfrutar la misma libre de ads.
Shazam: Aplicación conocida por todos aquellos clientes de iPhone, iPad, Android, BlackBerry y Nokia que nos permite detectar información sobre la canción que está sonando.
TextMe: Si bien soy una gran fan de WhatsApp, por el momento no tenemos una versión disponible para Windows Phone 7. Para seguir ahorrando en nuestros SMS, MMS, etcétera podemos hacer uso de TextMe (también disponible para iPhone) el cual nos aporta una función similar al mencionado anteriormente.
Microsoft Tag: Se trata de un lector de tags made in Microsoft :) con el que podremos descifrar y leer el contenido de los mismos.
Amazon Kindle: Otra de las aplicaciones que no podía faltar era el cliente de Amazon para la lectura de nuestros libros comprados en la gran tienda virtual de esta compañía.
WordPress: Gestor de nuestros blogs gestionados con WordPress. Nos permite tanto postear, administrar páginas, comentarios, etcétera.
Ebay: Excelente cliente para la conocida página de subastas donde podremos buscar, seguir, pujar, pagar e incluso enviar mensajes a los vendedores.
AppFinder: Aplicación complementaria para localizar contenido dentro del marketplace de Windows Phone 7. Actualmente el buscador por defecto del sistema operativo no está lo suficientemente optimizado y a veces se complica la localización de algunas aplicaciones.
NextGen Reader: Lector de RSS que nos permite sincronizar con nuestros feeds de Google Reader. Además nos ofrece modo offline, compartir artículos en Twitter, enviar feeds a Instapaper, entre otros.
Fruit Ninja: Juego ya conocido por los usuarios de apple donde debemos cortar todas aquellas frutas que aparezcan en pantalla como un autentico ninja :D ¡Cuidado! ¡Super adictivo! ;)
 
¿Alguien da más? :D 
 
¡Saludos!  

Subir un proyecto existente a Windows Azure

Una de las preguntas que me llegan a través del formulario de contacto es qué es lo necesario para subir una aplicación que ya tenemos implementada, en este caso con Web Forms, a la plataforma Windows Azure. En realidad, un proyecto para la nube contiene todos aquellos proyectos que componen nuestra aplicación y además un proyecto relacionado con la plataforma en el cual se define qué rol tiene el resto de proyectos de nuestra solución.

Cuando creamos una solución de tipo Cloud una de las ventanas que nos aparece es la siguiente:
 
En ella podemos seleccionar qué tipo de aplicaciones queremos implementar, desde aplicaciones web a aplicaciones en segundo plano. Sin embargo, uno de los escenarios más comunes es cuando no tenemos nada que implementar sino que únicamente queremos acondicionar su subida a la nube. En ese caso, no seleccionamos ninguno de los roles ofrecidos y pulsamos directamente en el botón OK. De esta forma, estamos pidiendo a Visual Studio 2010 crear una solución con un proyecto del tipo cloud sin ningún rol asociado.
 
Si en este momento tratáramos de ejecutar el proyecto, pulsando F5, Visual Studio nos devolvería el siguiente error:
 
En él se nos está avisando de que actualmente no hay ningún rol asociado al proyecto y que al menos es requerido uno del tipo web, worker o virtual machine. Llegado a este punto, debemos añadir  aquel proyecto(s) a la solución que queramos subir a Windows Azure Platform desempeñando uno de los roles.
Al igual que en cualquier solución convencional, copiamos/cortamos el proyecto que queramos añadir a la solución
 
y lo pegamos dentro de la carpeta del proyecto cloud.
 
Para que este aparezca dentro de la solución, hacemos clic con el botón derecho a nivel de solución y seleccionamos Add => Existing project…
 
y localizamos el archivo del proyecto que acabamos de mover dentro de la solución cloud.
 
Si bien este ya aparece dentro de la ventana Solution Explorer, todavía no forma parte del servicio que será desplegado en la nube. Para finalizar la configuración, debemos hacer clic con el botón derecho sobre la carpeta Roles y seleccionar Add => Web Role Project in solution…
 
Acto seguido nos aparecerá un cuadro de diálogo donde podremos seleccionar aquellos proyectos que encajen dentro de cualquiera de los roles existentes a día de hoy en la plataforma de Windows Azure.
 
Por otro lado habrá proyectos, por ejemplo de tipo Class Library, que no serán necesarios subirlos a la nube como tal sino únicamente las dlls resultantes del mismo.
Como nota adicional, es importante que nos aseguremos de que todas las librerías utilizadas en los proyectos ya existentes fuera de la plataforma y que queramos desplegar estén disponibles en la nube. Como solución podemos modificar las propiedades de las mismas como Copy Local = true o bien utilizar Startups.
 
Espero que sea de utilidad :D
 
¡Saludos! 

Windows Azure Startups

​Una de las cosas que más me gustan de la plataforma Windows Azure es que nuestras soluciones se convierten en un paquete capaz de acondicionar su entorno de vida :) Todos aquellos pasos previos, como la instalación de librerías, configuración de puertos en el firewall, etcétera, podemos definirlos gracias a la sección Startup del archivo ServiceDefinition.csdef

Esta sección nos permite ejecutar cualquier tipo de acción desatendida que sea necesaria para cada una de las instancias de nuestro rol. Para verlo con un ejemplo, voy a mostrar cómo sería posible la instalación de las librerías de ASP.NET MVC 3, ya que, a día de hoy, estas no están disponibles por defecto en las imágenes que utilizan las instancias de Windows Azure.
 
En primer lugar, creamos un projecto de tipo cloud sin seleccionar ningún rol. Para poder añadir un proyecto del tipo ASP.NET MVC 3, seleccionamos con el botón derecho sobre la solución y hacemos clic sobre Add -> New Project…
 

 

por último seleccionamos la plantilla ASP.NET MVC 3 Web Application (En mi caso la plantilla que he utilizado fue Internet Application) y esperamos a que la misma se genere.

 

 

Si llegados a este punto pulsamos F5 para ejecutar la aplicación, Visual Studio nos informará del siguiente error: 

 

 

El motivo es que, si bien hemos añadido una aplicación web a nuestro proyecto, la misma no está asociada con el proyecto cloud. Para ello, nos posicionamos en la carpeta Roles y, haciendo clic con el botón derecho sobre ella, seleccionamos Add -> Web Role Project in solution… 
 
Pulsamos F5 para comprobar que en local todo funciona correctamente :)
Una vez que tenemos nuestro proyecto listo, descargamos el ejecutable para la instalación llamado AspNetMVC3ToolsUpdateSetup.exe desde el siguiente enlace.

 

Este archivo debemos incluirlo dentro del proyecto y modificar las propiedades del mismo para que sea copiado en el paquete que posteriormente subiremos a la nube.
 

 
¡Perfecto! Ya tenemos nuestra solución con una aplicación ASP.NET MVC 3 y el ejecutable que instalará las librerías necesarias para que el sitio web funcione en Windows Azure. Como último paso, debemos definir el apartado Startup y definir una tarea donde indiquemos que es necesario instalar ASP.NET MVC 3 antes de que la aplicación esté disponible para los usuarios. Para ello, abrimos el archivo ServiceDefinition.csdef donde añadimos la sección Startup con los siguientes valores: 

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="Startups" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="MyASPNETMVC3">
    <Startup >
      <Task commandLine ="installaspnetmvc3.cmd" executionContext="elevated" taskType="simple"></Task>
    </Startup>
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
    </Endpoints>
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
  </WebRole>
</ServiceDefinition>
Dentro del apartado Startup podemos tener tantas tareas como sean necesarias con los siguiente parámetros: 
  • commandLine: Recibe como valor el nombre del programa o script que queremos ejecutar. En este caso vamos a invocar a un archivo llamado installaspnetmvc3.cmd, el cual situaremos en la raiz del proyecto web.

    En él vamos a incluir la llamada al archivo AspNetMVC3ToolsUpdateSetup.exe con la opción /q para indicar que debe ser una instalación “silenciosa” o desatendida ;)
  • E:approotfilesAspNetMVC3ToolsUpdateSetup.exe /q
    Nota: Existe un problema a la hora de generar scripts desde Visual Studio, el cual añade un byte para marcar todos los ficheros por defecto. Para evitar incidentes, recomiendo crear estos archivos con Notepad o modificar las opciones de guardado en File -> Advanced Save Options… donde deberemos seleccionar Unicode (UTF-8 without signature) – Codepage 650001 encoding.
  • executionContext: Nos permite indicar el nivel de permisos que queremos que tenga la tarea (limited o elevated)
  • taskType: Dependiendo de la implicación que tenga nuestra tarea en relación con el rol, podemos elegir entre:
    • simple: Se trata del tipo de tarea síncrona, la cual paraliza cualquier proceso hasta que la misma termina. Si no especificamos ningún tipo, esta es la opción por defecto.
    • background: Nuestra tarea se ejecutará a la par que otras (la ejecución de nuestro rol por ejemplo).
    • foreground: A diferencia del tipo anterior, cuando especificamos una tarea foreground esta se ejecutará de manera asíncrona como la anterior. La peculiaridad consiste en que el rol no podrá detenerse hasta que dicha tarea haya finalizado. 

 Si desplegamos nuestra aplicación en Windows Azure, podremos disfrutar de ASP.NET MVC 3 gracias a Startup section :D

Espero que haya sido de utilidad :)
¡Saludos!  

Zune: No installation media. Can’t find the media for installation package Windows Media Format SDK

 

 

Ahora que he vuelto de nuevo a mi Windows Phone 7, necesitaba instalar Zune para poder sincronizar todo mi stuff. Una vez descargado el paquete de instalación de la página oficial de Zune, me encuentro con el siguiente error:

 

Despues de pasarme un buen rato navegando, descubro que el problema es mi versión del sistema operativo: Windows 7 Ultimate N
A día de hoy existen distintos tipos de ediciones:
  • Windows 7: Esta edición sería la “estándar” donde incluye todo el repertorio típico de los sistemas operativos Windows para aquellos clientes que residen en países pertenecientes al Espacio Económico Europeo, Croacia y Suiza.
  • Windows 7 K: Sería la edición estándar, al igual que la anterior, pero para Corea.
  • Windows 7 N: Con esta edición podemos elegir nuestro propio reproductor multimedia y el software que queramos utilizar para administrar y reproducir CDs, DVDs, etcétera, es decir, no incluye Windows Media Player 12 por defecto como las dos versiones anteriores. Esta edición está pensada para los clientes del Espacio Económico Europeo, Croacia y Suiza al igual que la edición Windows 7.
  • Windows 7 KN: Exactamente igual que la versión anterior pero para Corea.
El problema reside en que es necesario tener instalado Windows Media Player 12 para poder instalar Zune en el sistema :( . Tanto si tenéis la versión N como la KN y aún así quereis tener Zune en vuestro equipo, es necesario descargar e instalar Media Feature Pack for Windows 7 N with Service Pack 1 and Windows 7KN with Service Pack 1 (KB968211)
Para más información sobre las ediciones N puedes consultar esta página.
Espero que sea de utilidad :D
¡Saludos!

Windows Azure Accelerator for Umbraco

 

 

Meses atrás explicaba en un artículo que escribí para MSDN España cómo era posible subir el CMS de Umbraco a Windows Azure. Si bien vimos que era posible, existían diversas dificultades que hacían de este gestor un funcionamiento algo desorientado a las aplicaciones escalables. El mayor problema era que el propio CMS almacenaba parte del contenido del sitio web en local, por lo que hacía imposible aumentar el número de frontales/instancias sin tocar el código fuente de Umbraco :( .

 

Después de la presentación en el MIX 2011 ya disponemos de un nuevo acelerador, con el que conseguimos desplegar la última versión del CMS adaptada de la siguiente manera:

 

 
Utilizando este esquema lo que se consigue es disponer de múltiples instancias de nuestro sitio web sincronizadas en todo momento (cada segundo) a través de un método llamado SyncForever dentro de la clase WebRole, típica  de los proyectos de Windows Azure como punto de entrada.

 

public override void Run()
{
    this.SyncForever(TimeSpan.FromSeconds(1));
}
Para descargar esta herramienta se puede hacer desde su sitio en codeplex.

 

 

¡Saludos!

 

Windows Azure Diagnostics (SDK 1.4)

En este post vamos a pararnos un poco más en profundidad en cada una de las fuentes de diagnóstico disponible a través de Microsoft.WindowsAzure.Diagnostics.dll.
Un punto importante a la hora de utilizar el sistema de diagnósticos de Windows Azure es que este trabaja conjuntamente con Windows Azure Storage, donde vamos a almacenar toda la información que cada una de las fuentes disponibles nos facilite.
Antes de centrarnos en la configuración, veamos qué podemos recuperar de nuestras instancias y dónde se almacena:
 
Fuente Descripción Destino
Windows Azure Logs En estos logs se guardan todas aquellas trazas registradas a través de la clase System.Diagnostics.Trace. Tabla
Performance Counters Se almacenan los contadores de rendimiento configurados previamente. Tabla
Windows Azure Diagnostic Infrastructure Logs Son todos aquellos registros relacionados con el servicio de Windows Azure. Tabla
Windows Event Logs Podemos añadir tanto fuentes predeterminadas de Windows, como System o Application, como aquellas dadas de alta programáticamente. Tabla
Crash Dumps Volcados de memoria de nuestra aplicación. Blob
Custom Error Logs Esta opción nos permite dar de alta nuestros propios logs dentro del proceso de transferencia de Windows Azure Diagnostics para poder recuperar los mismos a través del storage. Blob
IIS 7.0 Logs Podemos recuperar toda la información generada de forma automática relacionada con IIS Blob
Failed Request Logs Almacena información sobre aquellas peticiones fallidas de IIS Blob
Si bien cada una de las fuentes tiene su propia configuración, lo primero que debemos recuperar es la configuración inicial por defecto de los diagnósticos de la siguiente manera:
//We need to get default initial configuration
var config = DiagnosticMonitor.GetDefaultInitialConfiguration();
Generalmente esta configuración se recupera y se modifica en el archivo WebRole.cs o WorkerRole.cs en el método OnStart ya que es el punto de entrada de nuestra aplicación y se ejecuta cuando nuestras instancias se están iniciando.
En los siguientes apartados utilizaremos el objeto config para configurar cada una de las fuentes.

Windows Azure Logs

Esta primera fuente lo que nos va a permitir es almacenar en una tabla, generada de forma automática por el sistema de diagnósticos llamada WADLogsTable, todas aquellas líneas de registro que realicemos en nuestro código a través de System.Diagnostics.Trace, como por ejemplo:
Trace.WriteLine("WorkerRole_Diag entry point called", "Information");
Para poder recuperar estas trazas, debemos añadir el siguiente código:
//Windows Azure Logs. Table: WADLogsTable
config.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
config.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

Performance counters

Una de las fuentes más importantes para poder conocer el rendimiento de nuestros sistemas trata de los contadores de rendimiento. Para poder conocer cuál sería el nombre del contador que queremos añadir, podemos localizarlos en nuestro propio sistema:
 
 
Una vez elegidos los que queramos auditar, los agregamos al sistema de diagnóstico de la siguiente manera:
//Performance counters. Table: WADPerformanceCountersTable
 config.PerformanceCounters.DataSources.Add(
    new PerformanceCounterConfiguration
    {
        CounterSpecifier = @"Processor(*)*",
        SampleRate = TimeSpan.FromSeconds(1)
    }
 );

 config.PerformanceCounters.DataSources.Add(
    new PerformanceCounterConfiguration
    {
        CounterSpecifier = @"Memory*",
        SampleRate = TimeSpan.FromSeconds(1)
    }
 );

config.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

Windows Azure Diagnostic Infrastructure Log

Cuando trabajamos en local con development fabric podemos visualizar una consola por cada instancia que tengamos de nuestros roles donde nos facilita información de su estado.
 
 
Para poder recuperar esta información utilizaremos DiagnosticInfrastructureLogs para recuperar esta información en forma de tabla, la cual recibirá el nombre WADDiagnosticInfrastructureLogsTable:
//Windows Azure Diagnostic Infrastructure Logs. Table: WADDiagnosticInfrastructureLogsTable
config.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
config.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

Windows Event Logs

El visor de eventos de Windows creo que es algo que no necesita presentación :D . También podemos recuperar esta información a excepción de la fuente Security. Estos datos se nos presentarán a través de la tabla WADWindowsEventLogsTable.
//Windows Event Logs. Table: WADWindowsEventLogsTable
config.WindowsEventLog.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
config.WindowsEventLog.DataSources.Add("Application!*");
config.WindowsEventLog.DataSources.Add("System!*");
config.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

Crash Dumps

Uno de los clásicos no podía faltar :) Todo lo relacionado con los volcados de memoria se puede conseguir utilizando estas líneas:
//Crash Dumps. Blob. Container: wad-crash-dumps
CrashDumps.EnableCollection(true);
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
En este caso debemos tener en cuenta dos pasos: CrashDumps.EnableCollection nos permite habilitar la recolección tanto de mini dumps (parámetro a false) o full dumps (parámetro a true). Si sólo indicamos esta línea lo que vamos a conseguir es el almacenamiento local de estos volcados de memoria, pero no serán transferidos a nuestro storage. Para conseguir este segundo paso debemos especificar cada cuánto tiempo vamos a realizar la transferencia de los directorios de diagnóstico a través de config.Directories.ScheduledTransferPeriod como se indica en la segunda línea del código anterior.

Custom Error Logs

Imaginemos que ya tenemos un sistema de diagnóstico de terceros que no deseamos modificar, pero aun así queremos recuperar los ficheros generados de todas las instancias para poder procesarlos. En este caso podemos crear nuevos directorios de diagnóstico, lo cual nos va a permitir que los mismos sean transferidos cada cierto tiempo a los blobs de nuestra cuenta de storage:
//Custom Error Logs
var localResource = RoleEnvironment.GetLocalResource("CustomErrorStorage");
var directoryConfiguration = new DirectoryConfiguration
{
    Container = "wad-mycustom-log-container",
    DirectoryQuotaInMB = localResource.MaximumSizeInMegabytes,
    Path = localResource.RootPath
};

config.Directories.DataSources.Add(directoryConfiguration);
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);

IIS Logs

En el caso de los logs de IIS basta con configurar el tiempo de transferencia del apartado Directories, ya que se genera una carpeta donde almacena de forma automática la información:
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);

Failed Request Logs

Esta fuente está relacionada también con Internet Information Services tras la cual podemos recuperar todas aquellas peticiones fallidas. A excepción del resto, para poder configurar la misma debemos modificar el archivo web.config de nuestro web role para añadir la sección tracing dentro de system.webServer:
<system.webServer>
   <!-- Blob. Container: wad-iis-failedreqlogfiles -->
     <tracing>
       <traceFailedRequests>
          <add path="*">
             <traceAreas>
                <add provider="ASP" verbosity="Verbose" />
                <add provider="ASPNET"
                     areas="Infrastructure,Module,Page,AppServices"
                     verbosity="Verbose" />
                <add provider="ISAPI Extension" verbosity="Verbose" />
                <add provider="WWW Server"
                areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module"
                verbosity="Verbose" />
            </traceAreas>
            <failureDefinitions timeTaken="00:00:15" statusCodes="400-599" />
          </add>
        </traceFailedRequests>
      </tracing>
 <modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
Al generar esta información dentro de un archivo, necesitamos indicar el tiempo de transferencia de los directorios de diagnóstico como en los casos anteriores:
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
Nota: Todas aquellas fuentes que se almacenan en blobs generan una carpeta dentro del directorio DiagnosticStore para almacenar los archivos con la información. Para poder ser transferidos necesitamos indicar cada cuánto tiempo queremos que se envíe la información a Windows Azure Storage. Este tiempo de transferencia basta con definirlo una vez para todas las fuentes que usen este sistema.
Para que todos estos cambios tengan efecto, debemos iniciar la nueva configuración tomando como parámetros el nombre de la cadena de conexión que utilizará Windows Azure Diagnostics (por defecto Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString) y el objeto config que hemos personalizado:
//Start with new configuration
DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config);
Por último, como recomendación, existe una aplicación de Cerebrata llamada Azure Diagnostics Manager la cual nos va a facilitar mucho la interpretación de toda esta información de una forma muy visual y organizada.
Adjunto un proyecto de ejemplo donde podemos probar cada uno de los casos ;)
 
Espero que sea de utilidad :D
 
¡Saludos!

 

Cambiar la edición y el tamaño de nuestras bases de datos en SQL Azure

 

 
Cuando decidimos contratar SQL Azure como servidor de nuestras bases de datos relacionales lo primero que debemos estimar es el tamaño de nuestra base de datos. En la actualidad existen diferentes tamaños disponibles, agrupadas en dos ediciones:
  • Web edition
    • 1 GB
    • 5 GB
  • Business edition
    • 10 GB
    • 20 GB
    • 30 GB
    • 40 GB
    • 50 GB
Cuando queremos dar de alta una base de datos de cualquiera de estos tamaños podemos hacerlo bien a través del portal de Windows Azure:

 

a través de SQL Server 2008 R2 Management Studio:

 
 o bien utilizando directamente la siguiente sentencia SQL:

 

Create DATABASE mybbdd (EDITION='web',MAXSIZE=1GB)

 

Lo más lógico,  cuando utilizamos un modelo Pay as you go, es que vayamos adaptando el tamaño de nuestras base de datos cuando nuestro negocio lo requiera. A día de hoy el portal no nos ofrece una forma visual para modificar las características de las bases de datos existentes, por lo que es necesario modificar las mismas utilizando sentencias SQL. Cuando realizamos una modificación esta puede ser a nivel de edición y/o de tamaño:
ALTER DATABASE mybbdd MODIFY (EDITION='business', MAXSIZE=50GB)
 
ALTER DATABASE mybbdd MODIFY (EDITION='web', MAXSIZE=5GB)
Nota: En realidad, indicando sólo el tamaño es suficiente, ya que la edición será modificada automáticamente de web a business o viceversa si la situación lo requiere.
 
ALTER DATABASE mybbdd MODIFY (MAXSIZE=20GB)

 

 

Espero que sea de utilidad :D
¡Saludos!

Instalar Windows Azure Service Management CmdLets en Windows 7 SP 1 con Windows Azure SDK 1.4

Después de la nueva versión del SDK de Windows Azure y el Service Pack 1 de Windows 7, podemos encontrarnos ciertas trabas si intentamos instalar Windows Azure Service Management CmdLets:

 

 
Esto puede ocurrir principalmente por varios motivos:
  • Tenemos instalado el service pack 1 para Windows 7.
  • Hemos actualizado a Windows Azure SDK 1.4
  • Ambos :D
 Al no tener las nuevas versiones contempladas tanto en uno de los archivos de configuración como en uno de los script de powershell no puede reconocer las nuevas versiones tanto de compilación del sistema operativo como la del SDK. Para solucionarlo, podemos realizar los siguientes pasos:

Añadir el builder number de Windows 7 con sp 1

 
Dentro del directorio de WASM nos ubicamos en WASMCmdletssetup. Dentro de la misma tenemos un archivo llamado Dependencies.dep el cual lo abrimos con el Notepad para añadir el nuevo build number.
 
 
En este archivo podemos ver y modificar todas las dependencias necesarias para la instalación e incluso modificar la descripción y la url donde de donde podemos descargar la dependencia requerida. Centrándonos en el sistema operativo, como vemos en la imagen anterior, vemos que aparece un atributo llamado buildNumber el cual contiene todas las numeraciones de las compilaciones válidas. 7600 se corresponde con Windows 7 sin service pack. ¿Cómo sabemos cuál es la versión de compilación del sistema operativo? La forma más sencilla de llegar a este valor es abriendo una aplicación propietaria de Microsoft integrada en el sistema operativo que tenemos instalado. Por ejemplo, abrimos la aplicación Paint y pulsamos sobre About Paint/Sobre Paint.
 
 
Voilà! En este caso podemos confirmar que 7601 se corresponde con Windows 7 SP 1:D
El siguiente paso se trata de modificar uno de los powershell donde se verifica la versión del SDK de Windows Azure dentro del registro. En la versión anterior, el número anterior se correspondía con la 1.3.11122.0038.
 
 
Para que la comprobación se realice con éxito, necesitamos cambiar el valor de SearchVersion a 1.4.20227.1419 como se muestra en la imagen.
 
 
¡Listo! ya tenemos adaptadas todas las comprobaciones para lanzar de nuevo la instalación.
 
 
Espero que sea de utilidad :D
¡Saludos!

Refrescar un WebGrid cada X tiempo de forma asíncrona

Con la nueva versión ASP.NET MVC 3, disponemos de una nueva extensión para la creación de grids. Para conocer más detalles sobre este nuevo helper podéis consultar el artículo de Jose M. Aguilar :)
En este post me gustaría mostraros cómo es posible actualizar de forma asíncrona un grid cada un número determinado de segundos.

Del lado del servidor he adjuntado una base de datos con una única tabla para el ejemplo que os quiero mostrar:
 

Un repositorio para recuperar los valores:

using System.Linq;

namespace WebGridAsync.Models
{
    public class StuffRepository
    {
        private readonly StuffEntities _model;
        public StuffRepository()
        {
            _model = new StuffEntities();
        }

        public FileViewModel GetFiles(int page = 1)
        {
            var fileViewModel = new FileViewModel();
            var files = _model.Files.ToList();
            fileViewModel.FilesPerPages = 5;
            fileViewModel.NumberOfFiles = _model.Files.Count();
            fileViewModel.Files = files.Skip((page - 1) * fileViewModel.FilesPerPages)
                                       .Take(fileViewModel.FilesPerPages);
            return fileViewModel;
        }

        public void SaveChanges()
        {
            _model.SaveChanges();
        }
    }
}
Y por último un controlador donde lo que vamos a actualizar es el estado de los archivos en cada llamada:
using System.Web.Mvc;
using WebGridAsync.Models;

namespace WebGridAsync.Controllers
{
    public class HomeController : Controller
    {
        private readonly StuffRepository _stuffRepository;
        public HomeController()
        {
            _stuffRepository = new StuffRepository();
        }

        public ActionResult Index(int page = 1)
        {
            return View(GetFilesWithUpdatedStatus());
        }

        public FileViewModel GetFilesWithUpdatedStatus()
        {
            var fileViewModel = _stuffRepository.GetFiles();

            foreach (var myFile in fileViewModel.Files)
            {
                switch (myFile.Status)
                {
                    case "Pending":
                        myFile.Status = "Processing";
                        break;
                    case "Processing":
                        myFile.Status = "Waiting";
                        break;
                    case "Waiting":
                        myFile.Status = "More waiting...";
                        break;
                    case "More waiting...":
                        myFile.Status = "Completed";
                        break;
                    default:
                        myFile.Status = "Pending";
                        break;
                }
            }

            _stuffRepository.SaveChanges();
            return fileViewModel;
        }
    }
}
Por último, necesitamos crear una vista donde hagamos uso del helper WebGrid. Es importante que el mismo esté incluido en un div con un id asociado.
@model WebGridAsync.Models.FileViewModel
@{
    ViewBag.Title = "Async WebGrid";

    WebGrid grid = new WebGrid(rowsPerPage: Model.FilesPerPages, canSort: false);
    grid.Bind(Model.Files, rowCount: Model.NumberOfFiles);
}
<h2>@ViewBag.Message</h2>
<div id="myWebGrid">
    @grid.GetHtml(columns: new[]{
    grid.Column("Name"),
    grid.Column("Date"),
    grid.Column("Status")
})
</div>
Para hacer la llamada asíncrona, necesitamos utilizar algo de código javascript, con la ayuda de JQuery. En la misma página que el grid anterior incluimos lo siguiente:
<script language="javascript" type="text/javascript">

    $(document).ready(function () {
        $.ajaxSetup({
            cache: false
        });

        setTimeout(reloadAsync, 5000);
    });

    function reloadAsync() {
        $("#myWebGrid").load("/Home/Index #myWebGrid", function (response, status, xhr) {
            if (status == "error") {
                var msg = "Sorry but there was an error: ";
                $("#error").html(msg + xhr.status + " " + xhr.statusText);
            }
            else {
                setTimeout(reloadAsync, 5000);
            }

        });

    }
</script>
Lo que estamos haciendo en realidad es inicializar un timer para que cada 5 segundos solicite los datos al servidor. El método load de JQuery va a realizar una llamada a la acción Index del controlador Home para que este le devuelva la página renderizada. Una vez obtiene el resultado va a localizar el elemento div myWebGrid para reemplazar el que se está visualizando actualmente por el nuevo resultado.
Adjunto el proyecto por si fuera de utilidad :D
 
¡Saludos!

Configurar el proxy en Visual Studio 2010

Cuando trabajamos detrás de un proxy podemos experimentar algunos problemas con ciertas aplicaciones. Incluso Visual Studio puede verse perjudicado por ello :(

Para solucionarlo, podemos modificar el archivo de configuración de Visual Studio para especificar el uso del proxy por defecto.

En primer lugar cerramos todas las instancias de Visual Studio. Hacemos clic con el botón derecho sobre el acceso directo Microsoft Visual Studio 2010 para localizar la ubicación del ejecutable devenv.exe.
De todos los archivos que encontramos en el directorio, el que realmente nos interesa es devenv.exe.config que corresponde con el archivo de configuración del IDE.
Abrimos el mismo con Visual Studio y añadimos las siguientes líneas dentro de la sección <system.net>.
<defaultProxy useDefaultCredentials="true" enabled="true">
 <proxy usesystemdefault="True" />
</defaultProxy>

De tal manera que el archivo de configuración quede con el siguiente aspecto:

 

 

 
Si arrancamos de nuevo Visual Studio, ya podemos ejecutar aquellas acciones que requieran de autenticación en el proxy :D
Espero que sea de utilidad :)
¡Saludos!