127.0.0.1: Hogar dulce hogar

viernes, 17 de septiembre de 2010

[EBooks] Ebooks GRATIS de SQL Server 2008 R2 y Windows Server 2008 R2

Navegando navegando se encuentran multitud de recursos. En este caso y temporalmente he encontrado una oferta suculenta: la descarga de los siguientes ebooks:

image image

Efectivamente, es un libro de introducción a Windows Server 2008 R2 y otro a SQL Server 2008 R2. Simplemente yendo a la sección ofertas podemos encontrar los links de descarga de los libros, disponibles en PDF y XPS y previo login con nuestra cuenta de Windows Live.

¿Dónde los he encontrado? Pues en Microsoft Learning, que es el portal de Microsoft dedicado al aprendizaje y formación de todo el mundo, incluyendo las certificaciones y sus itinerarios. Recomiendo a todo el mundo que se pase por ahí y esté atento, pues en este caso las ofertas son tentadoras (dos buenos libros) y en otros casos puedes encontrar descuentos así como todo el soporte que requieras para tu información.

jueves, 16 de septiembre de 2010

[XNA] Lanzamiento XNA 4.0

Hoy se ha publicado por fin la versión 4.0 de XNA Game Studio, y como ya ocurrió en la beta ahora también se integran dentro de la Windows Phone Tool Developer Tools. Este kit incluye lo siguiente:

  • Visual Studio 2010 Express for Windows Phone
  • Windows Phone Emulator
  • Silverlight for Windows Phone
  • XNA Game Studio 4.0
  • Expression Blend
  • Como siempre, gratis y sin coste alguno para poder empezar o seguir trasteando con XNA y Windows Phone 7!

    miércoles, 15 de septiembre de 2010

    [WCF] Codificaciones de texto y controlando la serialización mediante eventos

    El motor de serialización de WCF está limitado a unos cuantos formatos de codificación y por defecto siempre codifica el tipo string en el formato UTF8. A priori no hay ningún problema, pero te puede ocurrir el siguiente escenario:

    Tenemos una serie de entidades serializadas con WCF en las que se almacena texto. Por ejemplo, objetos de negocio como artículos en una tienda en la que algunos de sus campos son la descripción, el nombre del artículo, además de todos aquellos que se crean necesarios. Partamos de la base de que hemos serializado nuestro objeto siguiendo el artículo correspondiente. En un momento determinado, comienzas a escribir la información de los objetos en el XML, de un modo a como sigue:

    <ArticleManager xmlns="http://schemas.datacontract.org/2004/07/Logic" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

    <Articles>

    <Article>

    <Name>Halo Reach</Name>

    <Description>La apasionante última entrega de la exitosa saga de shooters. </Description>

    </Article>

    </ArticleManager>

    Para una codificacion en UTF-8 no tendríamos ningún problema en deserializar el campo Name, puesto que todos los caracteres son válidos en bytes desde el punto de vista de esa codificación. Sin embargo, no ocurre lo mismo con el campo Description. Este campo incluye caracteres que no son válidos para esa coficación, como por ejemplo los caracteres con tildes (en última) y otros propios del castellano (como el caracter ñ). En el momento en que se deserializa ese dato, provoca una excepción en XmlSerializer por no encontrarse dentro del esquema de UTF8 y similares. ¿Qué podemos hacer? Muchas cosas, como por ejemplo establecer un XmlSerializer propio para nuestras clases de modo que los campos de tipo string se codifiquen y decodifiquen empleando las codificaciones que queramos, crear un decodificador propio exclusivo para manejar texto o bien lo que propongo aquí, que consiste en almacenar la información con bytes de cara al fichero XML pero mostrándola al usuario como string controlando mediante eventos los procesos de serialización y deserialización. Veamos cómo se puede hacer:

    Nuestra clase artículo tiene el siguiente juego de atributos:

       1: [DataContract()]
       2: public class Article
       3: {
       4:     [DataMember()]
       5:     public string Name;
       6:     [DataMember()]
       7:     public string Description;
       8: }

    Y lo que vamos a hacer es transformar y encapsular los campos miembros serializables dentro de arrays de bytes:

       1: [DataContract()]
       2: public class Article
       3: {
       4:     [DataMember()]
       5:     public byte[] ByteName;
       6:     [DataMember()]
       7:     public byte[] ByteDescription;
       8:  
       9:     public string Name;
      10:     public string Description;
      11:     ...
      12: }

    La idea es sencilla y se expuso anteriormente pero la recuerdo. Vamos a guardar los campos en el xml como bytes y al cargar el fichero, automáticamente se transforma en string. Para ello se proporcionan una serie de etiquetas de eventos que se pueden asociar a funciones de la clase que sufre el proceso para que actúen de manejadores del propio proceso. Estas etiquetas son:

    • OnDeserialized: Se invoca cuando el objeto ya se ha deserializado.
    • OnDeserializing: Se invoca justo antes de deserializar el objeto.
    • OnSerialized: Se invoca cuando el objeto ya ha pasado por el proceso de serialización.
    • OnSerializing: Se invoca justo antes de serializar el objeto.

    Debemos asociar posteriormente estas etiquetas a un método que nos sirva de manejador. Este método debe tener un único parámetro de tipo StreamingContext cuyo cometido es controlar el origen y destino de la secuencia de serialización. Dicho de otro modo más llano y campechano indica qué objeto es quien inicia la secuencia de datos (en este caso para la seriailzación/deserialización) a través de Context y con State indica cuál es el origen o destino de los datos. Esto último puede servir para especificar si es para un fichero, remoto, serializado, otra máquina, otro proceso, etc. Sabiendo esto, ya sólo nos falta escribir el método para deserializar:

       1: [OnDeserialized()]
       2: private void onDeserialize(StreamingContext context)
       3: {
       4:     this.Name = Encoding.Unicode.GetString(this.ByteName);
       5:     this.Description = Encoding.Unicode.GetString(this.ByteDescription);
       6: }

    Para habilitar caracteres con tildes, ñ y otros, he usado la codificación de Unicode que si permite usarlos. Como se aprecia, se invoca una vez el objeto ya está serializado y se han leído los miembros (los campos ByteName y ByteDesription tendrás sus oportunos valores). Ahora vayamos a por la serialización, que invocaremos antes de serializar para preparar los arrays de bytes:

       1: [OnSerializing()]
       2: private void onSerialize(StreamingContext context)
       3: {
       4:     this.ByteName = Encoding.Unicode.GetBytes(this.Name);
       5:     this.ByteDescription = Encoding.Unicode.GetBytes(this.Description);
       6: }

    Con este sencillo procedimiento no tendremos problemas de conversiones entre cualquier tipo de codificaciones.

    jueves, 9 de septiembre de 2010

    [SilverLight] Integración con HTML

    Uno de los temas más complicados o que por el momento no parece que tenga una solución clara es integrar HTML normal con una aplicación de SilverLight. Me explico con un sencillo ejemplo: supongamos el escenario de una aplicación en la que tenemos dentro un mininavegador donde podemos acceder a otras páginas. ¿Es posible? Evidentemente. ¿Es una solución bonita? En mi modesta opinión, no. ¿Y por qué voy a hablar de ello? Porque no he encontrado otras soluciones…

    Como primera medida encuentro la solución que se propone a través de este tutorial, empleando un control WebBrowser al que mediante su propiedad Source le podemos indicar el código html a carga. Podemos indicarlo mediante un típico enlace a página, creando un URI o bien añadiendo en el string el código html “a pelo”. El problema de todo esto es que para que el objeto WebBrowser funcione debe ejecutarse fuera del navegador (es un requerimiento del propio objeto). Si queremos que a través del propio navegador usemos html, tenemos la siguiente opción.

    Esta opción consiste en un tipo de fuerza bruta. Como principio básico conocemos que SilverLight no puede procesar el código HTML desde dentro del navegador, por lo que nuestra solución pasa por añadir un iframe desde el cual carguemos el código HTML y separarlo de la propia aplicación SilverLight (pero dentro de la misma aplicación ASP). El método es simple: creamos un tag div en la página principal, introducimos el iframe (podemos acceder a él a través del DOM) y le asignamos coordenadas absolutas, de forma que aparezca encima de la aplicación SilverLight:

       1: <iframe id="iframeReport" style="position:absolute;top:120px;left:0px;width:200px;height:200px;visibility:hidden;margin-left:15px;" src="http://www.google.com/"></iframe>
       1: System.Windows.Browser.HtmlElement myFrame = System.Windows.Browser.HtmlPage.Document.GetElementById("iframeReport"); 
       2: myFrame.SetStyleAttribute("visibility",

    Evidentemente hay varios componentes que intentan simular el comportamiento del HTML (como por ejemplo este), pero sin soporte oficial por parte del equipo de desarrollo de SilverLight.

    [Web] WebMatrix

    WebMatrix es un producto destinado al desarrollo web orientado a estudiantes y gente que aún no tiene un conocimiento muy amplio de la materia. Incluye todo lo necesario para comenzar:

    • IIS Developer Express: Un servidor web de desarrollo sobre el que podremos comprobar cómo funciona nuestra web.
    • ASP.NET: Nuestro querido framework para desarrollar web.
    • SQL Server Compact: Una base de datos embedida.

    En cuanto a la aplicación, dispone de la interfaz Ribbon (famosa por ser la interfaz de Office 2007 y usada en la mayoría de software incluido Windows 7) y acceso directo a Visual Studio para poder desarrollar mejor la web.

    Es un producto en fase beta, por lo que es muy posible que tenga algún fallo o cosilla que sea necesaria depurar. Por todo lo demás, pienso que es una buena idea el despojar de la complejidad el desarrollo web para pequeños sitios y en especial para todos aquellos que quieran aprender poco a poco y paso a paso antes de pasar por otro tipo de soluciones bastante más complejas.

    Aquí os dejo el enlace:

    http://www.microsoft.com/web/webmatrix

    martes, 24 de agosto de 2010

    [WCF] Desplegando en IIS, error 404.2

    Personalmente considero a la rama IT como algo sencillo desde el punto de vista idealista, puesto que muy, muy en el fondo son tareas que se pueden considerar mecánicas una vez conoces el funcionamiento de todo. El problema es cuando estás en proceso de aprender y tardas a veces más tiempo en configurar el despliegue que en otras tareas. Eso es lo que me ha pasado al desplegar un servicio WCF en IIS.

    Al desplegar mi servicio WCF obtenía el error 404.2 indicando que no podía acceder al servicio correspondiente, por lo que si no es visible para el propio servidor menos aún lo será para cualquier aplicación que desee consumirlo.

    El problema de acceso puede consistir en dos pasos fundamentales:

    • Algún problema en el webconfig (o no están bien definidos los endpoints del servicio o bien directamente no puede acceder al fichero). Para el primer punto basta con editarlo y arreglar la parte que está mal especificada y para la segunda basta verificar si el fichero es accesible por los permisos para el servidor y si está contemplado en las directivas de Filtrado de Solicitudes:image
    • No puede acceder al servicio debido a alguna restricción ISAPI o CGI, en cuyo caso deberemos comprobar el tipo de aplicación que permite ejecutar el servidor. En este caso, al emplear WCF deberemos asegurarnos que IIS se está ejecutando con la versión 4.x como mínimo de .NET Framework y que además, los filtros de las solicitudes ISAPI y CGI permiten la ejecución de estas características:image

    Una vez teniendo esto correctamente configurado, IIS ya podrá ejecutar nuestro servicio correctamente.

    miércoles, 18 de agosto de 2010

    [SilverLight] NotFound Exception

    Una de las mayores desventajas que nos podemos encontrar en SilverLight es la depuración de errores, en especial si estamos usando servicio WCF con RIA. Siempre podemos depurar la aplicación SilverLight cuando usemos Visual Studio, pero el problema es cuando disponemos de un servicio correctamente desplegado en IIS y nuestra aplicación falla al conectarse al servicio. El error más común al lanzar nuestra aplicación que se conecta a un servicio es una excepción de WCF indicando lo siguiente:

       1: {System.Net.WebException: El servidor remoto devolvió un error: NotFound. ---> System.Net.WebException: El servidor remoto devolvió un error: NotFound.
       2:    en System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
       3:    en System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
       4:    en System.Net.Browser.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)
       5:    --- Fin del seguimiento de la pila de excepciones internas ---
       6:    en System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
       7:    en System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
       8:    en System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)}

    Para ver qué esta ocurriendo realmente debemos realizar los siguientes pasos:

    1 – Debemos asegurarnos que nuestro servicio está creado perfectamente dentro del servidor (accediendo al servicio a través del mismo para comprobar que se ha creado correctamente).

    2 – Verificar si el ámbito del servicio y nuestra aplicación es el mismo. En el caso de que no lo sea, debemos especificar las políticas de acceso de dos modos: uno para las aplicaciones SilverLight y otro para el estándar de Adobe (como bien se indica en este artículo para SilverLight y este otro para dominios cruzados )

    3 – Por último nos queda establecer una directiva para poder imprimir la traza. La excepción de NotFound es un tanto ambigua, ya que aparentemente indica que no ha encontrado el servicio pero no indica por qué. Antes de dedicarse mucho tiempo a analizar la configuración del cliente y el servidor conviene primero imprimir la traza del error para conocer de primera mano qué es lo que impide al cliente conectarse con el servicio. Para ello debemos indicarlo expresamente mediante las siguientes líneas en el web.config (fichero de configuración del lado servidor):

     

    <system.serviceModel>

        <diagnostics>
          <messageLogging logEntireMessage="true"
            maxMessagesToLog="300"
            logMessagesAtServiceLevel="false"
            logMalformedMessages="true"
            logMessagesAtTransportLevel="true" />
        </diagnostics>

    </system.serviceModel>

    Poca explicación se puede añadir a esas líneas. Únicamente le estamos indicando que queremos activar el sistema de log, las características de los que admitimos y la capacidad del log.

    Por otra parte tenemos que añadir el siguiente nodo al XML:

    <system.diagnostics>
        <sources>
          <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
            <listeners>
             <add name="xml" type="System.Diagnostics.XmlWriterTraceListener"
               initializeData="c:\Temp\WcfMessage.log" />
            </listeners>
          </source>
        </sources>
        <trace autoflush="true" />
    </system.diagnostics>

    Donde evidentemente estamos indicando dónde se almacenará el log que podremos ir consultando. Por último, sólo falta indicarle a las clases de los servicios que queremos incluirlos en el sistema de logging especificándole el comportamiento IncludeExpcetionDetailInFaults en la cabecera de la clase:

       1: [ServiceBehavior(IncludeExceptionDetailInFaults= true)]
       2: public class Service
       3: {
       4: ...
       5: }

    Ahora, cada vez que se produzca un fallo podemos verlo en el fichero WcfMessage que hemos especificado para ver exactamente que es lo que está ocurriendo por debajo y así poder facilitar las tareas de depuración.