Reflector

En alguna ocasión, hemos necesitado conocer la forma de trabajar de un método de alguna librería en concreto. Tenemos dos formas de poder averiguarlo: Una es la imaginación 🙂 y la otra utilizar algún programa como Reflector. Resulta bastante útil para visualizar los métodos usados por muchas dlls del framework y otras aplicaciones. Podemos descargarlo de forma gratuita de la siguiente página:  www.red-gate.com/products/reflector/

Cuando arrancamos la aplicación, nos aparece una lista donde podemos elegir cuál es el framework que nos interesa cargar.


La interfaz de la aplicación no tiene mayor complejidad y vienen algunas dlls cargadas por defecto para el framework escogido.

Para visualizar el código, simplemente navegamos a través de las dlls y pulsamos  sobre la que nos interesa. En un principio, solamente vemos los prototipos de la clase que hemos seleccionado. Podemos mostrar los métodos simplemente pulsando en el link Expand Methods.

 

Por último, comentar que podemos añadir más librerías y mostrarlas en varios lenguajes como IL, C#, Visual Basic, Delphi, MC++ y Chrome.

Si alguien conoce más aplicaciones de este tipo, agradecería la contribución por si tienen más funcionalidad de la que reflector ofrece.

¡Saludos!

Acceder a SQL Azure con SQL Server Express 2008 Management Studio

Una vez que hemos conseguido activar nuestra cuenta de SQL Azure, comenzamos con la parte interesante: La creación y administración de las bases de datos.
Mientras la invitación de SQL Azure esté vigente, tenemos la posibilidad de crear cinco base de datos dentro del servidor que se nos ha asignado. En este caso, nada más entrar a http://sql.azure.com me he creado una base de datos Test. Hay que tener en cuenta que, para acceder después, debemos tener una contraseña que podemos resetear en la misma página. El usuario ya nos lo están facilitando.

Lo primero que se me ocurre hacer es intentar conectarme a mi nueva base de datos a través de SQL Server Express 2008 Management Studio introduciendo los datos que se me facilita en la página. En un principio, la suerte no está de mi lado:


Esto sucede cuando intentamos acceder a SQL Azure desde el cuadro de diálogo que aparece al inicio. Después de investigar en el foro creado para esta nueva tecnología, la solución que aportan por el momento es la siguiente:

1. Cerramos el cuadro de diálogo inicial de nuestro Management Studio.
2. Pulsamos sobre New Query (Nueva Consulta) y se volverá a abrir de nuevo un cuadro de diálogo para pedirnos los datos de conexión.
3. Introducimos nuestro Server Name, Server Admin (Login) y Password. El Server Name debe ser el que nos aparece en las cadenas de conexión que nos facilitan desde la página de SQL Azure. Para acceder a ellas, seleccionamos una de nuestras bases de datos y pulsamos el botón inferior de Connection Strings.

4. En la pestaña Connection Properties, escribimos el nombre de la base de datos a la que queremos conectar. En mi caso, será la base de datos Test.

5. Pulsamos en Connect y nos aparecerá un mensaje de error, aunque realmente es un warning.

A partir de ahora estamos conectados a nuestra base de datos. Resulta un poco incómodo por el hecho de no poder visualizar los objetos en el explorador. Aún así, podemos realizar cualquier tipo de consulta o administración a través de nuestra nueva ventana de consulta. Si yo escribo lo siguiente:

CREATE TABLE [Table_Test]
(
[id] int IDENTITY(1,1) NOT NULL
);
select * from Table_Test;


Y pulso F5, compruebo que efectivamente puedo comenzar a crear mis tables dentro de SQL Azure.

Por otro lado, cabe comentar que hay otra alternativa para conectarse y poder administrar nuestras bases de datos de una forma más visual. Se trata de de SQL Azure Manager y se puede acceder a través de este link.

¡Saludos!

Actualización 13/11/2009: Se han realizado los cambios pertinentes para esta incidencia. Estas modificaciones se pueden ver en el post Cambios en SQL Azure.

Subir una aplicación a Windows Azure

Versión Actualizada aquí

Una vez que tenemos agregado un servicio en Windows Azure, estamos preparados para subir nuestra aplicación a la nube. Normalmente, lo que debemos hacer, es subir la misma al entorno Staging y, una vez que hayamos realizado las pruebas oportunas, pasarla a producción para que nuestro servicio sea público.
Para trabajar con Windows Azure y Visual Studio necesitamos instalar una serie de complementos. Para acceder a ellos, nos dirigimos a www.microsoft.com/azure y pulsamos en el siguiente enlace:


En esta página se nos ofrecen una serie de links como las herramientas para Visual Studio, Windows Azure SDK y Microsoft .NET Service SDK. Haremos clic en cada uno de los enlaces para instalar los mismos.


Cuando finalicemos las instalaciones, abrimos nuestro Visual Studio, File => New => Project … y deberíamos tener una nueva plantilla llamada Cloud Service.

Cuando pulsamos OK, nos aparece una nueva ventana con tres tipos de proyectos más:

  • ASP.NET Web Role : Es una aplicación Web  estándar, preparada para funcionar en Windows Azure.
  • Worker Role: Es una aplicación que se ejecuta en segundo plano, como un servicio Windows, para Windows Azure.
  • CGI Web Role: Este proyecto se utiliza para correr aplicaciones FastCGI.

Seleccionamos ASP.NET Web Role y, a través los botones que aparecen en el centro,  añadimos la selección a la parte derecha de la ventana, modificando su nombre por Movies.WebRole.


A partir de este momento, tenemos dos proyectos en nuestra solución:

CloudService contiene la referencia de Movies.WebRole y además dos archivos necesarios para Windows Azure: ServiceConfiguration.cscfg, el cual incluye la configuración de nuestro servicio, instancias que tiene, etcétera y ServiceDefinition.csdef que contiene la metadata necesaria para que Windows Azure entienda cual es la forma de trabajar nuestra aplicación (En este archivo aparecen los roles de nuestra aplicación, endpoints, etc.)

Como realmente no me quiero extender en lo que es la codificación de un programa nuevo, únicamente voy a incluir un texto en el Default.aspx de Movies.WebRole, ya que solo quiero mostrar la forma de subir la aplicación a la nube.

   1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Movies.WebRole._Default" %>
   2:  
   3: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   4: <html xmlns="http://www.w3.org/1999/xhtml" >
   5: <head runat="server">
   6:     <title>Testing Windows Azure</title>
   7: </head>
   8: <body>
   9:     <form id="form1" runat="server">
  10:     <div>
  11:     Tutorial de Windows Azure desde <a href="http://returngis.blogspot.com/">Return(GiS);</a>
  12:     </div>
  13:     </form>
  14: </body>
  15: </html> 


Si pulsamos F5 para probar en local la misma, nos encontraríamos con este mensaje:

Lo único de lo que nos está advirtiendo es que Development Fabric necesita ser iniciado para poder arrancar este tipo de aplicación en local y que necesita que nuestro Visual Studio esté abierto con credenciales de administrador. Entonces, cerramos Visual Studio, hacemos clic sobre el icono del mismo y pulsamos sobre “Ejecutar como administrador”. Abrimos nuestra aplicación de nuevo y al pulsar F5 nos aparecerá un cuadro de diálogo distinto, preguntando si puede iniciar Development Storage con credenciales de Administrador.

Cuando damos permiso, aparecerá una nueva ventana donde nos informa de la inicialización de Development Storage y la instancia de SQL Server que está usando.


La aplicación arranca y dos iconos aparecen en nuestra barra de tareas:

Development Fabric es una interfaz de administración, donde podemos ver nuestro servicio, las instancias que tiene a su disposición y la consola del mismo.


Y, por otro lado, Development Storage:

Esta otra herramienta, depende de una instancia de SQL Server y se utiliza para el almacenamiento. En este caso, no es necesario Development Storage ya que no necesitamos almacenar absolutamente nada.

Sin entrar en más detalles por el momento, ha llegado la hora de publicar nuestra pequeña aplicación en la nube. Como si se tratara de una aplicación cualquiera, seleccionamos CloudService con el botón derecho y seleccionamos Publish…
Al hacer esto, ocurren dos cosas: Nos abre una ventana de nuestro explorador web que nos envía al portal de Azure y una ventana del explorador de Windows en la ubicación donde se encuentran los archivos que tendremos que subir.

En el explorador web, seleccionamos nuestro proyecto, hacemos clic en el servicio que tenemos preparado para nuestra aplicación y en el apartado Staging hacemos clic en el botón Deploy.
Se nos piden dos archivos: Aplication Package (CloudService) y Configuration Settings (ServiceConfiguration). Añadimos cada uno en su lugar, indicamos una etiqueta para este deploy  y pulsamos en el botón Deploy.
Aparecerá una ventana en blanco durante unos instantes y volveremos a la página de nuestro Servicio con la siguiente imagen:

Si ahora mismo pulsamos en la URL que nos ofrece, no funcionará ya que el servicio aún no está iniciado. Para ello, pulsamos en el botón Run.

Una vez que finalice, cambiará el estado a Initializing, el cual puede tardar un tiempo en cambiar a Started que es el que nos indicará que nuestra aplicación está lista para acceder en el entorno de Staging.


Ahora ya podemos probar en nuestro entorno de Staging de Windows Azure, sin necesidad de tenerlo públicamente en Internet. Cuando creamos que esté listo, es tan fácil como pulsar el botón de sincronización central y la nube se encargará de realizar el trabajo por nosotros.


Cuando realizamos la sincronización, nuestro entorno de Staging recupera la versión que estaba subida anteriormente en Producción, si es que existía alguna, y nuestra URL pública queda habilitada con nuestro nuevo servicio.

¡Saludos!

Extension Methods

Una de las nuevas funcionalidades de C# 3.0 fue la
posibilidad de ampliar los métodos de una clase ya existente. Con ello,
conseguimos aprovechar al máximo las clases ya predeterminadas, añadiéndole
alguna funcionalidad que nos es requerida para nuestra aplicación. De no ser así,
deberíamos tener estos métodos en clases distintas y perderíamos esa
unificación.

He recuperado un pequeño ejemplo de msdn, donde añadimos un nuevo método a la
clase String con el que podemos contar las palabras de una cadena.

Para ello, he creado un proyecto web con un texbox y un botón. Añado un
proyecto de tipo librería para almacenar mi clase “Extensions” dónde
especifico el nuevo método que agregaré a esta clase. De esta manera puedo utilizar mis extensiones en cualquier otro proyecto que lo necesite.

using System;

namespace Extensions
{
public static class Extensions
{
public static int ContarPalabras(this String str)
{
return str.Split(new[]{'','.','?'}, StringSplitOptions.RemoveEmptyEntries).Length;
}
}
}


Como podemos ver, creamos un método con el nombre que queremos que aparezca
dentro de nuestra clase. Como parámetros (aquí está la clave) le indicamos que
este método (this) pertenece a la clase String.
El contenido del mismo es exactamente igual que cualquier otro método. En este caso,
lo único que hacemos es crearnos un array, a raíz de un split realizado a la
cadena que está instanciada en nuestra clase String, y retornamos el tamaño de
ese array, omitiendo los blancos.
Importamos la librería a nuestro proyecto web y, si nos creamos un String y
comprobamos la lista de posibilidades nos aparecería lo siguiente:


Para comprobar esta funcionalidad, defino un evento click para mi botón y recojo la cadena introducida por el usuario para comprobar su tamaño.

using System;

namespace ExtensionMethod
{
public partial class Default : System.Web.UI.Page
{
protected void btnContar_Click(object sender, EventArgs e)
{
string cad = txtCadena.Text;
lblResult.Text = string.Format("La cadena tiene {0} palabras", cad.ContarPalabras());
}
}
}


 
¡Saludos!

Agregar un nuevo servicio en Windows Azure

Windows Azure es el nombre de la plataforma de servicios de Microsoft basada en cloud computing, tal y como nos cuenta Wikipedia.

Una vez que hemos conseguido nuestra cuenta para probar Azure, podemos comenzar a crear Servicios en la nube. Voy a comenzar con la configuración desde www.microsoft.com/azure, donde debemos crear un nuevo servicio para después publicarlo.

Al hacer clic en Windows Azure, nos abrirá una nueva ventana del explorador, y podremos seleccionar el proyecto, en el apartado My Proyects. Una vez realizado este paso, necesitamos agregar un nuevo servicio, haciendo clic en cualquiera de los dos link New Service que indico en la imagen:

En la siguiente ventana, solamente tenemos que escribir el nombre que tendrá nuestro servicio en la nube y una descripción del mismo. La descripción se podrá editar después de crear el servicio pero tened en cuenta que no ocurrirá lo mismo para el campo Service Label.

Ahora tenemos que pensar un dato importante: Necesitamos establecer el nombre público que tendrá nuestro servicio y comprobar si el que hemos seleccionado está aún disponible. Además se nos pregunta si nuestro servicio necesita ser hosteado en la misma ubicación de procedencia o si es indiferente. Este último punto, lo dejaremos como está por defecto.

Pulsamos en Create y esperamos a que nuestro servicio sea generado por Windows Azure.

Una vez que haya finalizado, tendremos dos entornos, Production y Staging, pero ninguno de los dos tendrá un Service Package subido aún, por lo que en estos momentos está preparado para recibir el paquete de nuestra aplicación.

 

¡Saludos!

Cómo obtener una cuenta para Windows Azure

Conseguir una cuenta para participar en Windows Azure es tarea complicada, sobre todo por el tiempo que tardan en dar una respuesta.
Voy a intentar explicar lo mejor posible la manera de obtener la invitación.
Es importante saber que hay dos tipos de invitaciones: Azure Service Invitations, la cual habilita Windows Azure y SQL Azure para trabajar únicamente con la base de datos. Existe una tercera funcionalidad, .NET Services, la cual no necesita invitación y se puede acceder a través de este link.

Para conseguir las otras dos invitaciones, podemos acceder directamente a la página de Microsoft Connect que es donde realmente nos redirige www.microsft.com/azure. Así nos evitamos la vuelta 😉

Nos pedirá una cuenta Passport y, si nunca hemos entrado a esta página, nos aparecerá una ventana como la siguiente:


Obviamente nos tenemos que registrar, nos informan de que nos van a solicitar información para el registro, tendremos que aceptar las condiciones de uso y, finalmente nos aparecerá una pantalla para ingresar nuestros datos:

Pulsamos el botón Aceptar y se nos solicita un nombre de usuario, el cual debe estar disponible dentro de Microsoft Connect para enviar comentarios, participar en publicaciones, etc.


Probamos suerte para ver cual está disponible y finalizamos el registro. A partir de este momento, pertenecemos a Microsoft Connect y tenemos a nuestra disponibilidad una cantidad considerable de proyectos en los que podemos participar.
Para localizar las invitaciones de Windows Azure y SQL Azure, tenemos que dirigirnos al Directorio de Conexiones.


Una vez allí, debemos localizar Azure Services Invitations y hacemos clic en Solicitar Participación Ahora.


Ahora tendremos que rellenar otro formulario con información relacionada con la empresa, cómo conociste Windows Azure, el nivel que tienes…


Y, al finalizarlo, aparecerá el siguiente mensaje:


En este apartado nos cuentan que nuestro código de invitación será enviado cuando esté disponible para Windows Azure, para SQL Azure exactamente igual, pero justo en el segundo punto tenemos un nuevo enlace dónde también debemos registrarnos para recibir el token de este último. Dentro de la página de SQL Azure Dev Centre, debemos hacer clic en el siguiente enlace y rellenar un formulario prácticamente igual que el de Applying to the Azure Services Invitations Program.


Finalizados todos estos pasos, en nuestro Panel de información de Connect, deberían aparecer tanto Azure Services Invitations como SQL Azure.


¡Pero esto acaba de comenzar! A partir de ahora, debemos esperar a que nos lleguen los correos oportunos con los tokens que se nos solicita en la página de Windows Azure.


Una vez que recibamos el email, deberemos introducir el token recibido por correo, para que algunos de los servicios queden habilitados (Windows Azure o SQL Azure). Hasta entonces poco más podemos hacer. Desconozco cuánto tiempo tardan en facilitarlos, pero en la solicitud de SQL Azure indican que debido a la demanda están tardando en responder.

Al menos, los que no lo hayan solicitado aún, pueden ir ganando tiempo.

¡Saludos!

Estructura de un proyecto ASP.NET MVC

MVC (Model View Controller) es un patrón de arquitectura, descrito por primera vez por  Trygve Reenskaug en el año 1979, que tiene como objetivo separar nuestra aplicación en tres capas fundamentalmente:

  • Modelo: Es la encargada del manejo de los datos de nuestra aplicación (Persistencia).
  • Vista: La interfaz de usuario, la cual no contiene absolutamente nada de lógica de negocio. En MVC las vistas no contienen un archivo .cs/.vb enlazado como pasaba en WebForms.
  • Controlador: Es la capa que actúa como intermediaria entre la Vista y el Modelo.

Es importante conocer cuál es el rol de cada una de las capas para no introducir código donde no corresponde. Es decir, el Modelo es el dueño de los datos, el Controlador es un simple intermediario (Ni le importa cómo accede el modelo a sus datos, ni le importa como la vista muestra la información) y la Vista no debe saber nada de la existencia del Modelo. Cada uno va a tener sus propios problemas creo yo 🙂

Actualmente tenemos la versión 1.0 como release y la versión 2.0 Preview 2. Os facilito el enlace de ambas ya que podemos tener instaladas las dos plantillas en nuestra máquina a la vez. (También podemos instalar el framework de MVC usando Web Platform Installer).

ASP.NET MVC 1.0

ASP.NET MVC 2.0 Preview 2

Si creamos un proyecto con cualquiera de las dos plantillas, obtendríamos el siguiente resultado:

 

  • /Content: Esta carpeta está pensada para almacenar los recursos de nuestra aplicación, como imágenes, estilos (CSS), etcétera.
  • /Controllers: Almacena todos los controladores de nuestro proyecto.
  • /Models: Todas las clases relacionadas con nuestra capa de datos.
  • /Scripts: Contiene los scripts que se ejecutan del lado del cliente.
  • /Views: Todas las vistas de todos los controladores. Dentro de la misma hay una carpeta por controlador.
  • /App_Data: Podemos almacenar nuestros archivos de datos.

Entonces… si cada controlador tiene su vista y disponemos de varias para cada uno ¿En qué vista comienza mi aplicación? Tenemos un archivo Global.asax que nos ayudará a definirlo.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using System.Web.Routing;

 

namespace MovieManagerTwo

{

    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 

    // visit http://go.microsoft.com/?LinkId=9394801

 

    public class MvcApplication : System.Web.HttpApplication

    {

        public static void RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 

            routes.MapRoute(

                "Default",                                              // Route name

                "{controller}/{action}/{id}",                           // URL with parameters

                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults

            );

 

        }

 

        protected void Application_Start()

        {

            RegisterRoutes(RouteTable.Routes);

        }

    }

}

Cuando la aplicación arranca, el método Application_Start() llama a su vez a RegisterRoutes. En él se puede apreciar que se crea una tabla de rutas y tenemos una ruta por defecto. En ella se indica el nombre del controlador, la acción que va a realizar y un parámetro id. En este caso vemos que el controlador que se ejecutará por defecto será HomeController y dentro del mismo se llamará a la acción Index. Tanto las acciones como la tabla de rutas lo veremos con más detenimiento. Por el momento es todo lo que necesitamos saber.

Si arrancamos la aplicación, podemos ver como efectivamente se ejecuta la acción Index del controlador Home.

Algunas de las ventajas que supone utilizar esta arquitectura pueden ser la siguientes:

  • El mantenimiento es más fácil debido a la división de responsabilidades.
  • No usa ViewState ni controles de servidor.
  • Es una arquitectura óptima para realizar pruebas unitarias (TDD).
  • Tenemos las herramientas necesarias para aplicar técnicas SEO.

Adjunto el Cheat Sheet dedicado al framework de MVC  que seguro que será de utilidad.

Para más información ASP.NET MVC.

 

¡Saludos!

Parámetros opcionales en C# 4.0

Una de las nuevas características preparadas para C# 4.0 son los parámetros opcionales,
ya conocidos por Visual Basic .NET. El objetivo será declarar nuestros
métodos, constructores e indexadores con unos valores por defecto, en
el caso de no indicarlos en la llamada.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5:  
   6: namespace ParametrosOpcionales
   7: {
   8:     class Program
   9:     {
  10:         static void Main(string[] args)
  11:         {
  12:             DatosPersonales("Gisela");
  13:             DatosPersonales("Gisela","Perez");
  14:             DatosPersonales("Gisela", "Perez", 10);
  15:  
  16:             System.Console.ReadLine();
  17:         }
  18:  
  19:         static void DatosPersonales(string nombre, string apellido = "Torres", int edad = 20)
  20:         {
  21:             System.Console.WriteLine("Nombre:{0} Apellido:{1} Edad:{2}", nombre, apellido, edad);
  22:         }

Podemos
realizar distintas llamadas indicando únicamente el obligatorio, el
obligatorio y uno de los opcionales o todos ellos. Visto así, podemos
preguntarnos cuál sería la manera de llamar a nuestro método pasándole
como argumentos el primer parámetro y el último, sin querer saber nada
del segundo. ¿Esto es posible? Afortunamente si y aquí es donde entran
en juego los argumentos nombrados, pensados para casos como este.

   1: DatosPersonales(nombre: "Jose");
   2: DatosPersonales(nombre: "Pedro",apellido:"Leal");
   3: DatosPersonales(edad: 40, apellido: "Rodriguez", nombre: "Laura");

Si utilizamos este tipo de llamada, incluso es posible alterar el orden de los parámetros.

Podemos
llegar a pensar en la posibilidad de olvidarnos de la sobrecarga en
algunos casos, sobre todo por el ahorro de código que esto supone.
También es cierto que podemos necesitar que la sobrecarga y los
parámetros opcionales convivan.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5:  
   6: namespace ParametrosOpcionales
   7: {
   8:     class Program
   9:     {
  10:         static void Main(string[] args)
  11:         {
  12:             ejemplo("Hola");
  13:  
  14:             System.Console.ReadLine();
  15:         }
  16:  
  17:         static void ejemplo(object saludo)
  18:         {
  19:             System.Console.WriteLine("Object: {0}",saludo);
  20:         }
  21:         static void ejemplo(string saludo,string nombre = "Gisela")
  22:         {
  23:             System.Console.WriteLine("{0} {1}",saludo,nombre);
  24:         }
  25:         static void ejemplo(string saludo)
  26:         {
  27:             System.Console.WriteLine("Simplemente {0}", saludo);
  28:         }
  29:     }
  30: }

En este ejemplo, existen tres tipos de sobrecarga. Si nosotros únicamente pasamos como argumento un string (“Hola”) debemos tener claro cual de los tres métodos será el candidato. Hay que tener en cuenta lo siguiente:

Siempre se eligirá en primer lugar aquel método que no necesite convertir el dato que le estamos pasando a otro tipo.

Tendrá preferencia aquel método que no necesite omitir sus parámetros opcionales.

Asi
pues, si arrancamos este ejemplo comprobaremos que la sobrecarga
elegida será la tercera por ser el arguménto del mismo tipo y por no
contenter parámetros opcionales que no se están teniendo en cuenta en
nuestra llamada.


¡Saludos!

SQL Server 2008 me impide modificar mis tablas

Cuando estamos diseñando las tablas de nuestra base de datos, es posible que necesitemos modificar la estructura de las mismas una vez creadas (Añadir claves primarias, modificar el nombre de las columnas, etcétera).

En SQL Server 2008 existe una protección, habilitada por defecto, para prevenir modificaciones en las tablas que ya han sido creadas. Si intentamos hacer cualquier cambio, al querer salvarlo,  nos aparecerá el siguiente mensaje:

 

“No se permite guardar los cambios. Los cambios que ha realizado
requieren que se quiten y vuelvan a crear las siguientes tablas. Quizá
ha realizado cambios en una tabla que no se puede volver a crear o ha
habilitado la opción Impedir guardar cambios que requieran volver a
crear tablas.”

Para deshabilitar esta protección vamos a Tools  => Options…  y en el apartado Designers deshabilitamos el checkbox Prevent saving changes that require table re-creation.

 

 

¡Saludos!

Este es mi nuevo hogar

Después de luchar con los estilos en Blogger, modificar todos los
menús, mejorar la búsqueda, etcétera … Pues nada, que me mudo 🙂

Ante todo, quiero dar las gracias a la gente que está detrás del nombre de Geeks.ms
por hacerme un rinconcito en este gran lugar, donde se puede encontrar
infinidad de información relacionada con el mundo de Microsoft.
Mi
intención es trasladar los posts a este nuevo sitio, redireccionar las
peticiones de Blogger y mejorar aquellos post que comencé en su momento
y quedaron pendientes de revisión.

Por último, quisiera pedir
disculpas a aquellas personas que estaban vinculadas al antiguo Blog,
aunque intentaré hacerlo de la forma más transparente posible.

… Blog nuevo, diseño nuevo … 😉 

¡Saludos!