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
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.
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.
¡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>
-
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
- 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
Zune: No installation media. Can’t find the media for installation package Windows Media Format SDK
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.
Windows Azure Accelerator for Umbraco
public override void Run() { this.SyncForever(TimeSpan.FromSeconds(1)); }
Windows Azure Diagnostics (SDK 1.4)
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 |
//We need to get default initial configuration var config = DiagnosticMonitor.GetDefaultInitialConfiguration();
Windows Azure Logs
Trace.WriteLine("WorkerRole_Diag entry point called", "Information");
//Windows Azure Logs. Table: WADLogsTable config.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose; config.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
Performance counters
//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
//Windows Azure Diagnostic Infrastructure Logs. Table: WADDiagnosticInfrastructureLogsTable config.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = LogLevel.Verbose; config.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
Windows Event Logs
//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
//Crash Dumps. Blob. Container: wad-crash-dumps CrashDumps.EnableCollection(true); config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
Custom Error Logs
//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
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
Failed Request Logs
<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>
config.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
//Start with new configuration DiagnosticMonitor.Start("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", config);
Cambiar la edición y el tamaño de nuestras bases de datos en SQL Azure
- Web edition
- 1 GB
- 5 GB
- Business edition
- 10 GB
- 20 GB
- 30 GB
- 40 GB
- 50 GB
a través de SQL Server 2008 R2 Management Studio:
Create DATABASE mybbdd (EDITION='web',MAXSIZE=1GB)
ALTER DATABASE mybbdd MODIFY (EDITION='business', MAXSIZE=50GB)
ALTER DATABASE mybbdd MODIFY (EDITION='web', MAXSIZE=5GB)
ALTER DATABASE mybbdd MODIFY (MAXSIZE=20GB)
Instalar Windows Azure Service Management CmdLets en Windows 7 SP 1 con Windows Azure SDK 1.4
-
Tenemos instalado el service pack 1 para Windows 7.
-
Hemos actualizado a Windows Azure SDK 1.4
-
Ambos
Añadir el builder number de Windows 7 con sp 1
Refrescar un WebGrid cada X tiempo de forma asíncrona
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(); } } }
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; } } }
@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>
<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>
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.
<defaultProxy useDefaultCredentials="true" enabled="true"> <proxy usesystemdefault="True" /> </defaultProxy>
De tal manera que el archivo de configuración quede con el siguiente aspecto: